1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
9 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 #if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
40 #pragma GCC diagnostic warning "-Wsign-compare"
44 #pragma warning( disable : 4018 )
47 //---------------------------------------------------------------------------
49 //---------------------------------------------------------------------------
51 #define OSG_COMPILEIMAGE
57 #include <boost/functional/hash/hash.hpp>
59 #include "OSGConfig.h"
61 #include "OSGImageGenericAtt.h"
62 #include "OSGFieldContainerFields.h"
63 #include "OSGFileSystem.h"
64 #include "OSGImageFileHandler.h"
65 #include "OSGSquish.h"
68 #include "OSGPathHandler.h"
69 #include "OSGSceneFileHandler.h"
77 1D/2D/3D Image with various pixel types data, can also optional hold
78 mipMap and simple multi-frame data.
81 /*------------------------------------------------------------------------*/
84 /*! Static dictionary to map pixelData values to the bytes per pixel
86 Internaly used in the createData() method.
89 UInt32
Image::_formatDic
[][2] =
102 { OSG_RGBA_DXT1
, 4 },
103 { OSG_RGBA_DXT3
, 4 },
104 { OSG_RGBA_DXT5
, 4 },
106 { OSG_DEPTH_STENCIL_PF
, 1 },
107 { OSG_ALPHA_INTEGER_PF
, 1 },
108 { OSG_RGB_INTEGER_PF
, 3 },
109 { OSG_RGBA_INTEGER_PF
, 4 },
110 { OSG_BGR_INTEGER_PF
, 3 },
111 { OSG_BGRA_INTEGER_PF
, 4 },
112 { OSG_LUMINANCE_INTEGER_PF
, 1 },
113 { OSG_LUMINANCE_ALPHA_INTEGER_PF
, 2 }
116 Int32
Image::_typeDic
[][2] =
118 { OSG_INVALID_IMAGEDATATYPE
, 0 },
119 { OSG_UINT8_IMAGEDATA
, 1 },
120 { OSG_UINT16_IMAGEDATA
, 2 },
121 { OSG_UINT32_IMAGEDATA
, 4 },
122 { OSG_FLOAT32_IMAGEDATA
, 4 },
123 { OSG_FLOAT16_IMAGEDATA
, 2 },
124 { OSG_INT16_IMAGEDATA
, 2 },
125 { OSG_INT32_IMAGEDATA
, 4 },
126 { OSG_UINT24_8_IMAGEDATA
, 4 }
129 /*----------------------------- class specific ----------------------------*/
131 void Image::initMethod(InitPhase ePhase
)
135 /*! Inform parents, when image was changed
138 void Image::changed(ConstFieldMaskArg whichField
,
142 MFParentFieldContainerPtr::const_iterator parentsIt
=
143 this->_mfParents
.begin();
145 MFParentFieldContainerPtr::const_iterator parentsEnd
=
146 this->_mfParents
.end();
148 while(parentsIt
!= parentsEnd
)
150 (*parentsIt
)->changed(
151 TypeTraits
<BitVector
>::One
<< parentsIt
.getParentFieldPos(),
152 ChangedOrigin::Child
,
158 if(0x0000 != (whichField
& DataTypeFieldMask
))
161 Int32 mapSizeType
= sizeof(_typeDic
) / sizeof(UInt32
[2]);
162 UInt32 typeFormat
= 0;
165 for(i
= 0; i
< mapSizeType
; i
++)
167 if(_typeDic
[i
][0] == _sfDataType
.getValue())
169 typeFormat
= _typeDic
[i
][1];
173 setComponentSize( typeFormat
);
176 if(0x0000 != (whichField
& (MipMapCountFieldMask
|
180 PixelFormatFieldMask
)))
182 setSideSize(calcMipmapSumSize(_sfMipMapCount
.getValue()));
185 if(0x0000 != (whichField
& (SideSizeFieldMask
| SideCountFieldMask
)))
187 setFrameSize(_sfSideSize
.getValue() * _sfSideCount
.getValue());
194 Inherited::changed(whichField
, origin
, details
);
197 /*----------------------------- output ------------------------------------*/
199 void Image::dump( UInt32
,
200 const BitVector
) const
202 const Char8
*pfStr
= "UNDEF_PIXEL_FORMAT";
203 const Char8
*typeStr
= "INVALID_IMAGEDATA_TYPE";
205 switch(getPixelFormat())
217 pfStr
= "LUMINANCE_ALPHA";
252 case OSG_DEPTH_STENCIL_PF
:
253 pfStr
= "DEPTH_STENCIL";
255 case OSG_ALPHA_INTEGER_PF
:
256 pfStr
= "ALPHA_INTEGER";
258 case OSG_RGB_INTEGER_PF
:
259 pfStr
= "RGB_INTEGER";
261 case OSG_RGBA_INTEGER_PF
:
262 pfStr
= "RGBA_INTEGER";
264 case OSG_BGR_INTEGER_PF
:
265 pfStr
= "BGR_INTEGER";
267 case OSG_BGRA_INTEGER_PF
:
268 pfStr
= "BGRA_INTEGER";
270 case OSG_LUMINANCE_INTEGER_PF
:
271 pfStr
= "LUMINANCE_INTEGER";
273 case OSG_LUMINANCE_ALPHA_INTEGER_PF
:
274 pfStr
= "LUMINANCE_ALPHA_INTEGER";
277 pfStr
= "UNKNOWN_PIXEL_FORMAT";
281 switch (getDataType())
283 case OSG_UINT8_IMAGEDATA
:
284 typeStr
= "IMAGEDATA_TYPE UCHAR8";
286 case OSG_UINT16_IMAGEDATA
:
287 typeStr
= "IMAGEDATA_TYPE UCHAR16";
289 case OSG_UINT32_IMAGEDATA
:
290 typeStr
= "IMAGEDATA_TYPE UCHAR32";
292 case OSG_FLOAT16_IMAGEDATA
:
293 typeStr
= "IMAGEDATA_TYPE FLOAT16";
295 case OSG_FLOAT32_IMAGEDATA
:
296 typeStr
= "IMAGEDATA_TYPE FLOAT32";
298 case OSG_INT16_IMAGEDATA
:
299 typeStr
= "IMAGEDATA_TYPE INT16";
301 case OSG_INT32_IMAGEDATA
:
302 typeStr
= "IMAGEDATA_TYPE INT32";
304 case OSG_UINT24_8_IMAGEDATA
:
305 typeStr
= "IMAGEDATA_TYPE UINT24_8";
309 typeStr
= "UNKNOWN_IMAGEDATA_TYPE";
313 FLOG (("ImageDump: %s; %d/%d/%d; #mm: %d, side %d, #frame: %d, "
314 "frameDelay %g, dataType %s, size: %ld\n",
327 // Return the number of components per pixel.
329 UInt8
Image::getComponents(void) const
331 UInt16 mapSizeFormat
= sizeof(_formatDic
) / sizeof(UInt32
[2]);
333 for(UInt16 i
= 0; i
< mapSizeFormat
; i
++)
335 if(_formatDic
[i
][0] == getPixelFormat())
336 return _formatDic
[i
][1];
339 FWARNING(("Image::getComponents: image %p has unknown pixel format 0x%x!",
340 static_cast<const void *>(this), getPixelFormat()));
345 /*------------------------------ set object data --------------------------*/
347 /*! method to set the image data. Use the doCopy parameter to specify, whether
348 the method should copy or link the pixel data.
350 bool Image::set( UInt32 pixelFormat
,
362 setPixelFormat(pixelFormat
);
364 setWidth (osgMax(1, width
));
365 setHeight (osgMax(1, height
));
366 setDepth (osgMax(1, depth
));
368 setMipMapCount(osgMax(1, mipmapCount
));
369 setSideCount (osgMax(1, sidecount
));
370 setFrameCount (osgMax(1, frameCount
));
372 setFrameDelay (frameDelay
);
378 return createData(data
, allocMem
);
381 /*! method to set the image from another image object.
382 Use the doCopy parameter to specify, whether
383 the method should copy or link the pixel data.
386 bool Image::set(Image
*image
)
388 this->set(image
->getPixelFormat(),
392 image
->getMipMapCount(),
393 image
->getFrameCount (),
394 image
->getFrameDelay (),
396 image
->getDataType (),
398 image
->getSideCount ());
402 /*! method to set only the image pixel data, all parameter (e. pixelFormat
403 width,height and depth) stay the same
406 bool Image::setData(const UChar8
*da
)
414 FWARNING(("Image::setData(Null) call\n"));
417 return (da
? true : false);
420 void Image::clearData(void)
422 editMFPixel()->clear();
423 // free unused memory.
425 tmp
.swap(*editMFPixel());
428 /*! method to update just a subregion of the image data
429 all paramter (e. pixelFormat,width,height,depth) stay the same
431 bool Image::setSubData( Int32 offX
,
439 UChar8
*dest
= editData();
442 FDEBUG(( "Image::setSubData (%d %d %d) - (%d %d %d) - src %p\n",
443 offX
, offY
, offZ
, srcW
, srcH
, srcD
, src
));
445 if (hasCompressedData())
447 FFATAL (("Invalid Image::setSubData for compressed image\n"));
453 FFATAL(("Invalid data pointer in Image::setSubData\n"));
457 // determine the area to actually copy
458 UInt32 xMin
= osgMax(0, offX
);
459 UInt32 yMin
= osgMax(0, offY
);
460 UInt32 zMin
= osgMax(0, offZ
);
462 UInt32 xMax
= osgMin(getWidth (), offX
+ srcW
);
463 UInt32 yMax
= osgMin(getHeight(), offY
+ srcH
);
464 UInt32 zMax
= osgMin(getDepth (), offZ
+ srcD
);
466 // fill the destination buffer with the subdata
467 UInt32 destIdx
, srcIdx
= 0;
469 for(UInt32 z
= zMin
; z
< zMax
; z
++)
471 for(UInt32 y
= yMin
; y
< yMax
; y
++)
473 lineSize
= (xMax
- xMin
) * getBpp();
474 destIdx
= ((z
* getHeight() + y
) * getWidth() + xMin
) * getBpp();
476 memcpy (&dest
[destIdx
], &src
[srcIdx
], size_t(lineSize
));
478 srcIdx
+= Int32((srcW
- (xMax
- xMin
)) * getBpp() + lineSize
);
480 srcIdx
+= (srcH
- (yMax
- yMin
)) * srcW
* getBpp();
486 /*! The Image is not just a 2D container. The class can hold 3D (volume)
487 and movie data. If we have 3D/singleFrame or 2D/multiFrame data without
488 mipmaps we can flip between this two formats by just swapping the
489 getFrameCount() and getDepth() values.
491 bool Image::flipDepthFrameData(void)
493 bool retCode
= false;
496 if((getMipMapCount() == 1) &&
497 ((getFrameCount() == 1) || (getDepth() == 1)))
499 value
= getFrameCount();
501 setFrameCount(getDepth());
508 FWARNING (("Cant flipDepthFrameData(); invalid data layout\n"));
514 /*! This method is used by the parser to fill the image with
515 string pixel data. It expects the data in VRML PixelTexture Format.
517 bool Image::addValue(const char *value
)
519 static Image
*currentImage
= 0;
520 static UChar8
*currentData
= 0;
525 bool isHead
= strchr(value
, ' ') ? true : false;
527 if (hasCompressedData())
529 FFATAL (("Invalid Image::addValue for compressed image\n"));
533 // make sure we only read one image at a time
534 if(currentImage
== this)
538 FDEBUG(("Start new read cycle in image::addValue()\n"));
545 FFATAL(("Additional image date for different image\n"));
556 PixelFormat pf
= Image::OSG_INVALID_PF
;
559 sscanf(value
, "%d %d %d", &width
, &height
, &pixelDepth
);
561 FDEBUG(("Image::addValue() set: w/h/bpp: %d/%d/%d\n",
562 width
, height
, pixelDepth
));
564 switch(getDataType())
566 case OSG_UINT8_IMAGEDATA
:
570 pf
= OSG::Image::OSG_L_PF
;
573 pf
= OSG::Image::OSG_LA_PF
;
576 pf
= OSG::Image::OSG_RGB_PF
;
579 pf
= OSG::Image::OSG_RGBA_PF
;
582 pf
= OSG::Image::OSG_INVALID_PF
;
583 FFATAL(("Invalid pixel depth: %d\n", pixelDepth
));
588 case OSG_UINT16_IMAGEDATA
:
592 pf
= OSG::Image::OSG_L_PF
;
595 pf
= OSG::Image::OSG_LA_PF
;
598 pf
= OSG::Image::OSG_RGB_PF
;
601 pf
= OSG::Image::OSG_RGBA_PF
;
604 pf
= OSG::Image::OSG_INVALID_PF
;
605 FFATAL(("Invalid pixel depth: %d\n", pixelDepth
));
610 case OSG_UINT32_IMAGEDATA
:
614 pf
= OSG::Image::OSG_L_PF
;
617 pf
= OSG::Image::OSG_LA_PF
;
620 pf
= OSG::Image::OSG_RGB_PF
;
623 pf
= OSG::Image::OSG_RGBA_PF
;
626 pf
= OSG::Image::OSG_INVALID_PF
;
627 FFATAL(("Invalid pixel depth: %d\n", pixelDepth
));
632 case OSG_FLOAT32_IMAGEDATA
:
636 pf
= OSG::Image::OSG_L_PF
;
639 pf
= OSG::Image::OSG_LA_PF
;
642 pf
= OSG::Image::OSG_RGB_PF
;
645 pf
= OSG::Image::OSG_RGBA_PF
;
648 pf
= OSG::Image::OSG_INVALID_PF
;
649 FFATAL(("Invalid pixel depth: %d\n", pixelDepth
));
654 case OSG_FLOAT16_IMAGEDATA
:
658 pf
= OSG::Image::OSG_L_PF
;
661 pf
= OSG::Image::OSG_LA_PF
;
664 pf
= OSG::Image::OSG_RGB_PF
;
667 pf
= OSG::Image::OSG_RGBA_PF
;
670 pf
= OSG::Image::OSG_INVALID_PF
;
671 FFATAL(("Invalid pixel depth: %d\n", pixelDepth
));
676 case OSG_INT16_IMAGEDATA
:
677 case OSG_INT32_IMAGEDATA
:
679 FFATAL((" 'addValue' NYI\n "));
684 setDataType(OSG_INVALID_IMAGEDATATYPE
);
685 FFATAL(("Invalid type of image data: %d\n", getDataType()));
688 if(pf
!= 0 && (width
> 0) && (height
> 0))
690 set(pf
, width
, height
);
692 currentData
= editData();
701 if(currentData
!= NULL
)
704 // TODO; should we check the bounds, should be done by the parser
706 v
= strtoul(value
, 0, strchr(value
, 'x') ? 16 : 10);
708 for(j
= getBpp(); j
--;)
710 *currentData
++ = UChar8( (v
>> (8 * j
)) & 255 );
716 return currentData
? true : false;
719 /*! It is a simple method to reformat the image pixelFormat (not the size).
720 So you can for example convert a RGBA to RGB or RGB to Grey image.
722 bool Image::reformat(const Image::PixelFormat pixelFormat
,
724 Int32 iCompressionFlags
)
727 const UChar8
*sourceData
= NULL
;
728 UInt32 srcI
, destI
, destSize
= 0;
731 ImageUnrecPtr
dest(destination
);
733 if (hasCompressedData())
735 FFATAL (("Invalid Image::reformat for compressed image\n"));
739 if(destination
== NULL
)
741 dest
= Image::create();
744 FINFO(("Try to reformat image from pixelDepth %d to %d\n",
748 if(iCompressionFlags
== 0)
750 iCompressionFlags
= (osgsquish::kColourMetricPerceptual
|
751 osgsquish::kColourRangeFit
);
754 iCompressionFlags
&= ~0x07;
756 // TODO !!! code all the cases !!!
759 pixelFormat
!= OSG_INVALID_PF
&&
760 (destination
!= 0 || (pixelFormat
!= static_cast<Image::PixelFormat
>(getPixelFormat()))))
763 dest
->set(pixelFormat
,
775 sourceData
= getData();
777 data
= dest
->editData();
778 destSize
= dest
->getSize();
780 const UInt16
*sourceDataUC16
=
781 reinterpret_cast<const UInt16
*>(sourceData
);
783 UInt16
*destDataUC16
= reinterpret_cast<UInt16
*>(data
);
785 const UInt32
*sourceDataUC32
=
786 reinterpret_cast<const UInt32
*>(sourceData
);
788 UInt32
*destDataUC32
= reinterpret_cast<UInt32
*>(data
);
790 const Real32
*sourceDataF32
=
791 reinterpret_cast<const Real32
*>(sourceData
);
793 Real32
*destDataF32
= reinterpret_cast<Real32
*>(data
);
795 const Real16
*sourceDataH16
=
796 reinterpret_cast<const Real16
*>(sourceData
);
798 Real16
*destDataH16
= reinterpret_cast<Real16
*>(data
);
802 switch (getPixelFormat())
804 //-----------------------------------------------------
811 switch (getDataType())
813 case OSG_UINT8_IMAGEDATA
:
814 case OSG_UINT16_IMAGEDATA
:
815 case OSG_UINT32_IMAGEDATA
:
816 case OSG_FLOAT32_IMAGEDATA
:
817 case OSG_FLOAT16_IMAGEDATA
:
818 memcpy (data
, getData(), destSize
);
822 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
828 switch (getDataType())
830 case OSG_UINT8_IMAGEDATA
:
831 for (srcI
= destI
= 0; destI
< destSize
;)
833 data
[destI
++] = sourceData
[srcI
];
834 data
[destI
++] = sourceData
[srcI
++];
837 case OSG_UINT16_IMAGEDATA
:
838 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
840 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
841 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
844 case OSG_UINT32_IMAGEDATA
:
845 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
847 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
848 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
851 case OSG_FLOAT32_IMAGEDATA
:
852 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
854 destDataF32
[destI
++] = sourceDataF32
[srcI
];
855 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
859 case OSG_FLOAT16_IMAGEDATA
:
860 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
862 destDataH16
[destI
++] = sourceDataH16
[srcI
];
863 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
867 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
873 switch (getDataType())
875 case OSG_UINT8_IMAGEDATA
:
876 for (srcI
= destI
= 0; destI
< destSize
;)
878 data
[destI
++] = sourceData
[srcI
];
879 data
[destI
++] = sourceData
[srcI
];
880 data
[destI
++] = sourceData
[srcI
++];
883 case OSG_UINT16_IMAGEDATA
:
884 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
886 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
887 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
888 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
891 case OSG_UINT32_IMAGEDATA
:
892 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
894 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
895 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
896 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
899 case OSG_FLOAT32_IMAGEDATA
:
900 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
902 destDataF32
[destI
++] = sourceDataF32
[srcI
];
903 destDataF32
[destI
++] = sourceDataF32
[srcI
];
904 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
907 case OSG_FLOAT16_IMAGEDATA
:
908 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
910 destDataH16
[destI
++] = sourceDataH16
[srcI
];
911 destDataH16
[destI
++] = sourceDataH16
[srcI
];
912 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
916 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
922 switch (getDataType())
924 case OSG_UINT8_IMAGEDATA
:
925 for (srcI
= destI
= 0; destI
< destSize
;)
927 data
[destI
++] = sourceData
[srcI
];
928 data
[destI
++] = sourceData
[srcI
];
929 data
[destI
++] = sourceData
[srcI
];
930 data
[destI
++] = sourceData
[srcI
++];
933 case OSG_UINT16_IMAGEDATA
:
934 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
936 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
937 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
938 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
939 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
942 case OSG_UINT32_IMAGEDATA
:
943 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
945 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
946 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
947 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
948 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
951 case OSG_FLOAT32_IMAGEDATA
:
952 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
954 destDataF32
[destI
++] = sourceDataF32
[srcI
];
955 destDataF32
[destI
++] = sourceDataF32
[srcI
];
956 destDataF32
[destI
++] = sourceDataF32
[srcI
];
957 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
960 case OSG_FLOAT16_IMAGEDATA
:
961 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
963 destDataH16
[destI
++] = sourceDataH16
[srcI
];
964 destDataH16
[destI
++] = sourceDataH16
[srcI
];
965 destDataH16
[destI
++] = sourceDataH16
[srcI
];
966 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
970 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
975 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
980 //-----------------------------------------------------
987 switch (getDataType())
989 case OSG_UINT8_IMAGEDATA
:
990 memcpy (data
, getData(), destSize
);
992 case OSG_UINT16_IMAGEDATA
:
993 memcpy (data
, getData(), destSize
);
995 case OSG_UINT32_IMAGEDATA
:
996 memcpy (data
, getData(), destSize
);
998 case OSG_FLOAT32_IMAGEDATA
:
999 memcpy (data
, getData(), destSize
);
1001 case OSG_FLOAT16_IMAGEDATA
:
1002 memcpy (data
, getData(), destSize
);
1006 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1012 switch (getDataType())
1014 case OSG_UINT8_IMAGEDATA
:
1015 for (srcI
= destI
= 0; destI
< destSize
;)
1017 data
[destI
++] = sourceData
[srcI
];
1018 data
[destI
++] = sourceData
[srcI
++];
1021 case OSG_UINT16_IMAGEDATA
:
1022 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1024 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1025 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1028 case OSG_UINT32_IMAGEDATA
:
1029 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1031 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1032 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1035 case OSG_FLOAT32_IMAGEDATA
:
1036 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1038 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1039 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1043 case OSG_FLOAT16_IMAGEDATA
:
1044 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1046 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1047 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1051 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1057 switch (getDataType())
1059 case OSG_UINT8_IMAGEDATA
:
1060 for (srcI
= destI
= 0; destI
< destSize
;)
1062 data
[destI
++] = sourceData
[srcI
];
1063 data
[destI
++] = sourceData
[srcI
];
1064 data
[destI
++] = sourceData
[srcI
++];
1067 case OSG_UINT16_IMAGEDATA
:
1068 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1070 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1071 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1072 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1075 case OSG_UINT32_IMAGEDATA
:
1076 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1078 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1079 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1080 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1083 case OSG_FLOAT32_IMAGEDATA
:
1084 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1086 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1087 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1088 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1091 case OSG_FLOAT16_IMAGEDATA
:
1092 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1094 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1095 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1096 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1100 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1106 switch (getDataType())
1108 case OSG_UINT8_IMAGEDATA
:
1109 for (srcI
= destI
= 0; destI
< destSize
;)
1111 data
[destI
++] = sourceData
[srcI
];
1112 data
[destI
++] = sourceData
[srcI
];
1113 data
[destI
++] = sourceData
[srcI
];
1114 data
[destI
++] = sourceData
[srcI
++];
1117 case OSG_UINT16_IMAGEDATA
:
1118 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1120 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1121 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1122 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1123 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1126 case OSG_UINT32_IMAGEDATA
:
1127 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1129 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1130 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1131 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1132 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1135 case OSG_FLOAT32_IMAGEDATA
:
1136 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1138 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1139 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1140 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1141 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1144 case OSG_FLOAT16_IMAGEDATA
:
1145 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1147 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1148 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1149 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1150 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1154 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1159 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1165 //-----------------------------------------------------
1167 switch (pixelFormat
)
1172 switch (getDataType())
1174 case OSG_UINT8_IMAGEDATA
:
1175 memcpy (data
, getData(), destSize
);
1177 case OSG_UINT16_IMAGEDATA
:
1178 memcpy (data
, getData(), destSize
);
1180 case OSG_UINT32_IMAGEDATA
:
1181 memcpy (data
, getData(), destSize
);
1183 case OSG_FLOAT32_IMAGEDATA
:
1184 memcpy (data
, getData(), destSize
);
1186 case OSG_FLOAT16_IMAGEDATA
:
1187 memcpy (data
, getData(), destSize
);
1191 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1197 switch (getDataType())
1199 case OSG_UINT8_IMAGEDATA
:
1200 for (srcI
= destI
= 0; destI
< destSize
;)
1202 data
[destI
++] = sourceData
[srcI
];
1203 data
[destI
++] = sourceData
[srcI
++];
1206 case OSG_UINT16_IMAGEDATA
:
1207 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1209 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1210 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1213 case OSG_UINT32_IMAGEDATA
:
1214 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1216 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1217 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1220 case OSG_FLOAT32_IMAGEDATA
:
1221 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1223 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1224 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1228 case OSG_FLOAT16_IMAGEDATA
:
1229 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1231 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1232 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1236 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1242 switch (getDataType())
1244 case OSG_UINT8_IMAGEDATA
:
1245 for (srcI
= destI
= 0; destI
< destSize
;)
1247 data
[destI
++] = sourceData
[srcI
];
1248 data
[destI
++] = sourceData
[srcI
];
1249 data
[destI
++] = sourceData
[srcI
++];
1252 case OSG_UINT16_IMAGEDATA
:
1253 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1255 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1256 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1257 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1260 case OSG_UINT32_IMAGEDATA
:
1261 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1263 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1264 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1265 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1268 case OSG_FLOAT32_IMAGEDATA
:
1269 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1271 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1272 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1273 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1276 case OSG_FLOAT16_IMAGEDATA
:
1277 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1279 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1280 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1281 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1285 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1291 switch (getDataType())
1293 case OSG_UINT8_IMAGEDATA
:
1294 for (srcI
= destI
= 0; destI
< destSize
;)
1296 data
[destI
++] = sourceData
[srcI
];
1297 data
[destI
++] = sourceData
[srcI
];
1298 data
[destI
++] = sourceData
[srcI
];
1299 data
[destI
++] = sourceData
[srcI
++];
1302 case OSG_UINT16_IMAGEDATA
:
1303 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1305 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1306 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1307 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1308 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1311 case OSG_UINT32_IMAGEDATA
:
1312 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1314 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1315 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1316 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1317 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1320 case OSG_FLOAT32_IMAGEDATA
:
1321 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1323 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1324 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1325 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1326 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1329 case OSG_FLOAT16_IMAGEDATA
:
1330 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1332 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1333 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1334 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1335 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1339 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1344 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1349 //-----------------------------------------------------
1351 switch (pixelFormat
)
1354 switch (getDataType())
1356 case OSG_UINT8_IMAGEDATA
:
1357 for (srcI
= destI
= 0; destI
< destSize
;)
1360 data
[destI
++] = sourceData
[srcI
++];
1363 case OSG_UINT16_IMAGEDATA
:
1364 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1367 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1370 case OSG_UINT32_IMAGEDATA
:
1371 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1374 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1377 case OSG_FLOAT32_IMAGEDATA
:
1378 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1381 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1384 case OSG_FLOAT16_IMAGEDATA
:
1385 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1388 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1392 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1398 switch (getDataType())
1400 case OSG_UINT8_IMAGEDATA
:
1401 for (srcI
= destI
= 0; destI
< destSize
;)
1403 data
[destI
++] = sourceData
[srcI
++];
1407 case OSG_UINT16_IMAGEDATA
:
1408 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1410 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1414 case OSG_UINT32_IMAGEDATA
:
1415 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1417 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1421 case OSG_FLOAT32_IMAGEDATA
:
1422 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1424 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1428 case OSG_FLOAT16_IMAGEDATA
:
1429 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1431 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1436 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1441 switch (getDataType())
1443 case OSG_UINT8_IMAGEDATA
:
1444 memcpy (data
, getData(), destSize
);
1446 case OSG_UINT16_IMAGEDATA
:
1447 memcpy (data
, getData(), destSize
);
1449 case OSG_UINT32_IMAGEDATA
:
1450 memcpy (data
, getData(), destSize
);
1452 case OSG_FLOAT32_IMAGEDATA
:
1453 memcpy (data
, getData(), destSize
);
1455 case OSG_FLOAT16_IMAGEDATA
:
1456 memcpy (data
, getData(), destSize
);
1459 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1465 switch (getDataType())
1467 case OSG_UINT8_IMAGEDATA
:
1468 for (srcI
= destI
= 0; destI
< destSize
;)
1470 data
[destI
++] = sourceData
[srcI
];
1471 data
[destI
++] = sourceData
[srcI
];
1472 data
[destI
++] = sourceData
[srcI
++];
1476 case OSG_UINT16_IMAGEDATA
:
1477 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1479 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1480 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1481 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1485 case OSG_UINT32_IMAGEDATA
:
1486 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1488 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1489 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1490 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1494 case OSG_FLOAT32_IMAGEDATA
:
1495 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1497 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1498 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1499 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1503 case OSG_FLOAT16_IMAGEDATA
:
1504 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1506 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1507 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1508 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1513 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1519 switch (getDataType())
1521 case OSG_UINT8_IMAGEDATA
:
1522 for (srcI
= destI
= 0; destI
< destSize
;)
1524 data
[destI
++] = sourceData
[srcI
];
1525 data
[destI
++] = sourceData
[srcI
];
1526 data
[destI
++] = sourceData
[srcI
++];
1527 data
[destI
++] = sourceData
[srcI
++];
1530 case OSG_UINT16_IMAGEDATA
:
1531 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1533 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1534 destDataUC16
[destI
++] = sourceDataUC16
[srcI
];
1535 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1536 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1539 case OSG_UINT32_IMAGEDATA
:
1540 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1542 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1543 destDataUC32
[destI
++] = sourceDataUC32
[srcI
];
1544 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1545 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1548 case OSG_FLOAT32_IMAGEDATA
:
1549 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1551 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1552 destDataF32
[destI
++] = sourceDataF32
[srcI
];
1553 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1554 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1557 case OSG_FLOAT16_IMAGEDATA
:
1558 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1560 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1561 destDataH16
[destI
++] = sourceDataH16
[srcI
];
1562 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1563 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1567 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1572 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1577 //-----------------------------------------------------
1579 switch (pixelFormat
)
1584 switch (getDataType())
1586 case OSG_UINT8_IMAGEDATA
:
1587 for (srcI
= destI
= 0; destI
< destSize
;)
1590 sum
+= sourceData
[srcI
++];
1591 sum
+= sourceData
[srcI
++];
1592 sum
+= sourceData
[srcI
++];
1593 data
[destI
++] = sum
/ 3;
1596 case OSG_UINT16_IMAGEDATA
:
1597 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1600 sum
+= sourceDataUC16
[srcI
++];
1601 sum
+= sourceDataUC16
[srcI
++];
1602 sum
+= sourceDataUC16
[srcI
++];
1603 destDataUC16
[destI
++] = sum
/ 3;
1606 case OSG_UINT32_IMAGEDATA
:
1607 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1610 sum
+= sourceDataUC32
[srcI
++];
1611 sum
+= sourceDataUC32
[srcI
++];
1612 sum
+= sourceDataUC32
[srcI
++];
1613 destDataUC32
[destI
++] = sum
/ 3;
1616 case OSG_FLOAT32_IMAGEDATA
:
1617 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1620 sumReal
+= sourceDataF32
[srcI
++];
1621 sumReal
+= sourceDataF32
[srcI
++];
1622 sumReal
+= sourceDataF32
[srcI
++];
1623 destDataF32
[destI
++] = sumReal
/ 3.0;
1626 case OSG_FLOAT16_IMAGEDATA
:
1627 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1630 sumReal
+= sourceDataH16
[srcI
++];
1631 sumReal
+= sourceDataH16
[srcI
++];
1632 sumReal
+= sourceDataH16
[srcI
++];
1633 destDataH16
[destI
++] = sumReal
/ 3.0;
1637 FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
1642 switch (getDataType())
1644 case OSG_UINT8_IMAGEDATA
:
1645 for (srcI
= destI
= 0; destI
< destSize
;)
1648 sum
+= sourceData
[srcI
++];
1649 sum
+= sourceData
[srcI
++];
1650 sum
+= sourceData
[srcI
++];
1651 data
[destI
++] = sum
/ 3;
1652 data
[destI
++] = sum
/ 3;
1655 case OSG_UINT16_IMAGEDATA
:
1656 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1659 sum
+= sourceDataUC16
[srcI
++];
1660 sum
+= sourceDataUC16
[srcI
++];
1661 sum
+= sourceDataUC16
[srcI
++];
1662 destDataUC16
[destI
++] = sum
/ 3;
1663 destDataUC16
[destI
++] = sum
/ 3;
1666 case OSG_UINT32_IMAGEDATA
:
1667 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1670 sum
+= sourceDataUC32
[srcI
++];
1671 sum
+= sourceDataUC32
[srcI
++];
1672 sum
+= sourceDataUC32
[srcI
++];
1673 destDataUC32
[destI
++] = sum
/ 3;
1674 destDataUC32
[destI
++] = sum
/ 3;
1677 case OSG_FLOAT32_IMAGEDATA
:
1678 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1681 sumReal
+= sourceDataF32
[srcI
++];
1682 sumReal
+= sourceDataF32
[srcI
++];
1683 sumReal
+= sourceDataF32
[srcI
++];
1684 destDataF32
[destI
++] = sumReal
/ 3.0;
1685 destDataF32
[destI
++] = sumReal
/ 3.0;
1688 case OSG_FLOAT16_IMAGEDATA
:
1689 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1692 sumReal
+= sourceDataH16
[srcI
++];
1693 sumReal
+= sourceDataH16
[srcI
++];
1694 sumReal
+= sourceDataH16
[srcI
++];
1695 destDataH16
[destI
++] = sumReal
/ 3.0;
1696 destDataH16
[destI
++] = sumReal
/ 3.0;
1700 FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
1705 switch (getDataType())
1707 case OSG_UINT8_IMAGEDATA
:
1708 memcpy (data
, getData(), destSize
);
1710 case OSG_UINT16_IMAGEDATA
:
1711 memcpy (data
, getData(), destSize
);
1713 case OSG_UINT32_IMAGEDATA
:
1714 memcpy (data
, getData(), destSize
);
1716 case OSG_FLOAT32_IMAGEDATA
:
1717 memcpy (data
, getData(), destSize
);
1719 case OSG_FLOAT16_IMAGEDATA
:
1720 memcpy (data
, getData(), destSize
);
1723 FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
1729 switch (getDataType())
1731 case OSG_UINT8_IMAGEDATA
:
1732 for (srcI
= destI
= 0; destI
< destSize
;)
1735 sum
+= data
[destI
++] = sourceData
[srcI
++];
1736 sum
+= data
[destI
++] = sourceData
[srcI
++];
1737 sum
+= data
[destI
++] = sourceData
[srcI
++];
1738 data
[destI
++] = sum
/ 3;
1741 case OSG_UINT16_IMAGEDATA
:
1742 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1745 sum
+= destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1746 sum
+= destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1747 sum
+= destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
1748 destDataUC16
[destI
++] = sum
/ 3;
1751 case OSG_UINT32_IMAGEDATA
:
1752 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1755 sum
+= destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1756 sum
+= destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1757 sum
+= destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
1758 destDataUC32
[destI
++] = sum
/ 3;
1761 case OSG_FLOAT32_IMAGEDATA
:
1762 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1765 sumReal
+= destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1766 sumReal
+= destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1767 sumReal
+= destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1768 destDataF32
[destI
++] = sumReal
/ 3.0;
1771 case OSG_FLOAT16_IMAGEDATA
:
1772 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1775 sumReal
+= destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1776 sumReal
+= destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1777 sumReal
+= destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1778 destDataH16
[destI
++] = sumReal
/ 3.0;
1782 FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
1786 #if defined(GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
1789 iCompressionFlags
|= osgsquish::kDxt1
;
1792 Int32 iStorage
= osgsquish::GetStorageRequirements(getWidth(),
1796 OSG_ASSERT(iStorage
== Int32(destSize
));
1799 osgsquish::CompressImage(sourceData
,
1808 #if defined(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
1811 iCompressionFlags
|= osgsquish::kDxt1
;
1814 Int32 iStorage
= osgsquish::GetStorageRequirements(getWidth(),
1818 OSG_ASSERT(iStorage
== Int32(destSize
));
1821 osgsquish::CompressImage(sourceData
,
1830 #if defined(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
1833 iCompressionFlags
|= osgsquish::kDxt3
;
1836 Int32 iStorage
= osgsquish::GetStorageRequirements(getWidth(),
1840 OSG_ASSERT(iStorage
== Int32(destSize
));
1843 osgsquish::CompressImage(sourceData
,
1852 #if defined(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
1855 iCompressionFlags
|= osgsquish::kDxt5
;
1858 Int32 iStorage
= osgsquish::GetStorageRequirements(getWidth(),
1862 OSG_ASSERT(iStorage
== Int32(destSize
));
1865 osgsquish::CompressImage(sourceData
,
1876 FWARNING (( "RGB: Invalid target IMAGE_DATA_TYPE\n" ));
1882 //-----------------------------------------------------
1885 switch (pixelFormat
)
1888 switch (getDataType())
1890 case OSG_UINT8_IMAGEDATA
:
1891 for (srcI
= destI
= 0; destI
< destSize
;)
1894 data
[destI
++] = sourceData
[srcI
++];;
1897 case OSG_UINT16_IMAGEDATA
:
1898 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1901 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];;
1904 case OSG_UINT32_IMAGEDATA
:
1905 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1908 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];;
1911 case OSG_FLOAT32_IMAGEDATA
:
1912 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1915 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
1918 case OSG_FLOAT16_IMAGEDATA
:
1919 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1922 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
1926 FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
1933 switch (getDataType())
1935 case OSG_UINT8_IMAGEDATA
:
1936 for (srcI
= destI
= 0; destI
< destSize
;)
1939 sum
+= sourceData
[srcI
++];
1940 sum
+= sourceData
[srcI
++];
1941 sum
+= sourceData
[srcI
++];
1942 data
[destI
++] = sum
/ 3;
1946 case OSG_UINT16_IMAGEDATA
:
1947 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1950 sum
+= sourceDataUC16
[srcI
++];
1951 sum
+= sourceDataUC16
[srcI
++];
1952 sum
+= sourceDataUC16
[srcI
++];
1953 destDataUC16
[destI
++] = sum
/ 3;
1957 case OSG_UINT32_IMAGEDATA
:
1958 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1961 sum
+= sourceDataUC32
[srcI
++];
1962 sum
+= sourceDataUC32
[srcI
++];
1963 sum
+= sourceDataUC32
[srcI
++];
1964 destDataUC32
[destI
++] = sum
/ 3;
1968 case OSG_FLOAT32_IMAGEDATA
:
1969 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1972 sumReal
+= sourceDataF32
[srcI
++];
1973 sumReal
+= sourceDataF32
[srcI
++];
1974 sumReal
+= sourceDataF32
[srcI
++];
1975 destDataF32
[destI
++] = sumReal
/ 3.0;
1979 case OSG_FLOAT16_IMAGEDATA
:
1980 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
1983 sumReal
+= sourceDataH16
[srcI
++];
1984 sumReal
+= sourceDataH16
[srcI
++];
1985 sumReal
+= sourceDataH16
[srcI
++];
1986 destDataH16
[destI
++] = sumReal
/ 3.0;
1991 FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
1997 switch (getDataType())
1999 case OSG_UINT8_IMAGEDATA
:
2000 for (srcI
= destI
= 0; destI
< destSize
;)
2003 sum
+= sourceData
[srcI
++];
2004 sum
+= sourceData
[srcI
++];
2005 sum
+= sourceData
[srcI
++];
2006 data
[destI
++] = sum
/ 3;
2007 data
[destI
++] = sourceData
[srcI
++];;
2010 case OSG_UINT16_IMAGEDATA
:
2011 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
2014 sum
+= sourceDataUC16
[srcI
++];
2015 sum
+= sourceDataUC16
[srcI
++];
2016 sum
+= sourceDataUC16
[srcI
++];
2017 destDataUC16
[destI
++] = sum
/ 3;
2018 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];;
2021 case OSG_UINT32_IMAGEDATA
:
2022 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
2025 sum
+= sourceDataUC32
[srcI
++];
2026 sum
+= sourceDataUC32
[srcI
++];
2027 sum
+= sourceDataUC32
[srcI
++];
2028 destDataUC32
[destI
++] = sum
/ 3;
2029 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];;
2032 case OSG_FLOAT32_IMAGEDATA
:
2033 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
2036 sumReal
+= sourceDataF32
[srcI
++];
2037 sumReal
+= sourceDataF32
[srcI
++];
2038 sumReal
+= sourceDataF32
[srcI
++];
2039 destDataF32
[destI
++] = sumReal
/ 3.0;
2040 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
2043 case OSG_FLOAT16_IMAGEDATA
:
2044 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
2047 sumReal
+= sourceDataH16
[srcI
++];
2048 sumReal
+= sourceDataH16
[srcI
++];
2049 sumReal
+= sourceDataH16
[srcI
++];
2050 destDataH16
[destI
++] = sumReal
/ 3.0;
2051 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
2055 FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
2061 switch (getDataType())
2063 case OSG_UINT8_IMAGEDATA
:
2064 for (srcI
= destI
= 0; destI
< destSize
;)
2066 data
[destI
++] = sourceData
[srcI
++];
2067 data
[destI
++] = sourceData
[srcI
++];
2068 data
[destI
++] = sourceData
[srcI
++];
2072 case OSG_UINT16_IMAGEDATA
:
2073 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
2075 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
2076 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
2077 destDataUC16
[destI
++] = sourceDataUC16
[srcI
++];
2081 case OSG_UINT32_IMAGEDATA
:
2082 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
2084 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
2085 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
2086 destDataUC32
[destI
++] = sourceDataUC32
[srcI
++];
2090 case OSG_FLOAT32_IMAGEDATA
:
2091 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
2093 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
2094 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
2095 destDataF32
[destI
++] = sourceDataF32
[srcI
++];
2099 case OSG_FLOAT16_IMAGEDATA
:
2100 for (srcI
= destI
= 0; destI
< destSize
/getComponentSize();)
2102 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
2103 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
2104 destDataH16
[destI
++] = sourceDataH16
[srcI
++];
2109 FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
2115 switch (getDataType())
2117 case OSG_UINT8_IMAGEDATA
:
2118 memcpy (data
, getData(), destSize
);
2120 case OSG_UINT16_IMAGEDATA
:
2121 memcpy (data
, getData(), destSize
);
2123 case OSG_UINT32_IMAGEDATA
:
2124 memcpy (data
, getData(), destSize
);
2126 case OSG_FLOAT32_IMAGEDATA
:
2127 memcpy (data
, getData(), destSize
);
2129 case OSG_FLOAT16_IMAGEDATA
:
2130 memcpy (data
, getData(), destSize
);
2133 FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
2138 #if defined(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
2141 iCompressionFlags
|= osgsquish::kDxt1
;
2144 Int32 iStorage
= osgsquish::GetStorageRequirements(getWidth(),
2148 OSG_ASSERT(iStorage
== Int32(destSize
));
2151 osgsquish::CompressImage(sourceData
,
2159 #if defined(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
2162 iCompressionFlags
|= osgsquish::kDxt3
;
2165 Int32 iStorage
= osgsquish::GetStorageRequirements(getWidth(),
2169 OSG_ASSERT(iStorage
== Int32(destSize
));
2172 osgsquish::CompressImage(sourceData
,
2180 #if defined(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
2183 iCompressionFlags
|= osgsquish::kDxt5
;
2186 Int32 iStorage
= osgsquish::GetStorageRequirements(getWidth(),
2190 OSG_ASSERT(iStorage
== Int32(destSize
));
2193 osgsquish::CompressImage(sourceData
,
2209 #if defined(GL_DEPTH_STENCIL_EXT) || defined(GL_DEPTH_STENCIL_NV)
2210 case OSG_DEPTH_STENCIL_PF
:
2212 case OSG_ALPHA_INTEGER_PF
:
2213 case OSG_RGB_INTEGER_PF
:
2214 case OSG_RGBA_INTEGER_PF
:
2215 case OSG_BGR_INTEGER_PF
:
2216 case OSG_BGRA_INTEGER_PF
:
2217 case OSG_LUMINANCE_INTEGER_PF
:
2218 case OSG_LUMINANCE_ALPHA_INTEGER_PF
:
2222 FFATAL((" 'reformat' NYI\n "));
2227 FWARNING (( "Unvalid pixeldepth (%d) in reformat() !\n",
2233 // rip the data from the local destImage if necessary
2234 if(destination
== NULL
)
2241 return (data
? true : false);
2244 void Image::swapDataEndian(void)
2246 UChar8
*data
= editData();
2248 UInt32 size
= getSize() / getComponentSize();
2249 UInt16
*dataUC16
= reinterpret_cast<UInt16
*>(data
);
2250 UInt32
*dataUC32
= reinterpret_cast<UInt32
*>(data
);
2251 Real32
*dataF32
= reinterpret_cast<Real32
*>(data
);
2254 switch (getDataType())
2256 case OSG_UINT8_IMAGEDATA
:
2260 case OSG_UINT16_IMAGEDATA
:
2262 for(UInt32 i
=0;i
<size
;++i
)
2264 UInt16 p
= dataUC16
[i
];
2266 dataUC16
[i
] = (((p
>> 8)) | (p
<< 8));
2270 case OSG_UINT32_IMAGEDATA
:
2272 for(UInt32 i
=0;i
<size
;++i
)
2274 UInt32 p
= dataUC32
[i
];
2277 (((p
& 0x000000FF) << 24) | ((p
& 0x0000FF00) << 8) |
2278 ((p
& 0x00FF0000) >> 8) | ((p
& 0xFF000000) >> 24) );
2283 case OSG_FLOAT32_IMAGEDATA
:
2285 for(UInt32 i
=0;i
<size
;++i
)
2287 Real32 p
= dataF32
[i
];
2288 UInt8
*b
= reinterpret_cast<UInt8
*>(&p
);
2290 std::swap(b
[0], b
[3]);
2291 std::swap(b
[1], b
[2]);
2297 case OSG_INT16_IMAGEDATA
:
2298 case OSG_INT32_IMAGEDATA
:
2300 FFATAL((" 'swapDataEndian' NYI\n "));
2305 FWARNING (( "invalid source data type \n"));
2310 /*! It is a simple method to convert the image dataType. Does not change
2311 the pixelFormat. So you can for example convert a image consisting of
2312 UChar8 data to Float data.
2315 bool Image::convertDataTypeTo(Int32 destDataType
)
2317 if (hasCompressedData())
2319 FFATAL (("Invalid Image::convertDataTypeTo for compressed image\n"));
2323 if(destDataType
== getDataType())
2325 FWARNING (( "source image and destination image have same data "
2326 "types: no conversion possible"));
2330 FINFO(("Try to convert image from dataType %d to %d\n",
2331 getDataType(), destDataType
));
2335 dest
= Image::create();
2337 dest
->set(getPixelFormat(),
2349 const UChar8
*sourceData
= getData();
2350 UChar8
*destData
= dest
->editData();
2352 UInt32 sourceSize
= getSize() / getComponentSize();
2354 const UInt16
*sourceDataUC16
= reinterpret_cast<const UInt16
*>(sourceData
);
2355 UInt16
*destDataUC16
= reinterpret_cast< UInt16
*>(destData
);
2356 const UInt32
*sourceDataUC32
= reinterpret_cast<const UInt32
*>(sourceData
);
2357 UInt32
*destDataUC32
= reinterpret_cast< UInt32
*>(destData
);
2358 const Real32
*sourceDataF32
= reinterpret_cast<const Real32
*>(sourceData
);
2359 Real32
*destDataF32
= reinterpret_cast< Real32
*>(destData
);
2360 // const Real16 *sourceDataH16 = reinterpret_cast<const Real16 *>(sourceData);
2361 Real16
*destDataH16
= reinterpret_cast< Real16
*>(destData
);
2363 switch (getDataType())
2365 case OSG_UINT8_IMAGEDATA
:
2367 switch (destDataType
)
2369 case OSG_UINT16_IMAGEDATA
:
2371 for (UInt32 i
= 0; i
< sourceSize
; i
++)
2373 destDataUC16
[i
] = UInt16(sourceData
[i
]<<8);
2377 case OSG_UINT32_IMAGEDATA
:
2379 for (UInt32 i
= 0; i
< sourceSize
; i
++)
2381 destDataUC32
[i
] = UInt32(sourceData
[i
]<<24);
2385 case OSG_FLOAT32_IMAGEDATA
:
2387 for (UInt32 i
= 0; i
< sourceSize
; i
++)
2389 destDataF32
[i
] = Real32(sourceData
[i
]/255.0);
2393 case OSG_FLOAT16_IMAGEDATA
:
2395 for (UInt32 i
= 0; i
< sourceSize
; i
++)
2397 destDataH16
[i
] = Real16(sourceData
[i
]/255.0);
2402 FWARNING (( "invalid destination data type \n" ));
2408 case OSG_UINT16_IMAGEDATA
:
2410 switch (destDataType
)
2412 case OSG_UINT8_IMAGEDATA
:
2414 UInt16 nMin
= UInt16(65535);
2415 UInt16 nMax
= UInt16(0 );
2417 for (UInt32 i
= 0; i
< sourceSize
; ++i
)
2419 if(sourceDataUC16
[i
] > nMax
)
2420 nMax
= sourceDataUC16
[i
];
2422 if(sourceDataUC16
[i
] < nMin
)
2423 nMin
= sourceDataUC16
[i
];
2426 Real32 fRange
= Real32(nMax
- nMin
);
2430 for(UInt32 i
= 0; i
< sourceSize
; ++i
)
2435 for(UInt32 i
= 0; i
< sourceSize
; ++i
)
2439 (Real32 (sourceDataUC16
[i
] - nMin
)) /
2446 case OSG_UINT32_IMAGEDATA
:
2448 for (UInt32 i
= 0; i
< sourceSize
; i
++)
2450 destDataUC32
[i
] = UInt32(sourceDataUC16
[i
]<<16);
2454 case OSG_FLOAT32_IMAGEDATA
:
2456 for (UInt32 i
= 0; i
< sourceSize
; i
++)
2458 destDataF32
[i
] = Real32(sourceDataUC16
[i
]/65535.0);
2463 case OSG_FLOAT16_IMAGEDATA
:
2465 for (UInt32 i
= 0; i
< sourceSize
; i
++)
2467 destDataH16
[i
] = Real16(sourceDataUC16
[i
]/255.0);
2472 FWARNING (( "invalid destination data type \n" ));
2477 case OSG_UINT32_IMAGEDATA
:
2479 switch (destDataType
)
2481 case OSG_UINT8_IMAGEDATA
:
2483 UInt32 nMin
= UInt32(4294967295ul);
2484 UInt32 nMax
= UInt32(0 );
2486 for (UInt32 i
= 0; i
< sourceSize
; ++i
)
2488 if(sourceDataUC32
[i
] > nMax
)
2489 nMax
= sourceDataUC32
[i
];
2491 if(sourceDataUC32
[i
] < nMin
)
2492 nMin
= sourceDataUC32
[i
];
2495 Real32 fRange
= Real32(nMax
- nMin
);
2499 for(UInt32 i
= 0; i
< sourceSize
; ++i
)
2504 for(UInt32 i
= 0; i
< sourceSize
; ++i
)
2508 (Real32(sourceDataUC32
[i
] - nMin
)) /
2515 case OSG_UINT16_IMAGEDATA
:
2517 UInt32 nMin
= UInt32(4294967295ul);
2518 UInt32 nMax
= UInt32(0 );
2520 for(UInt32 i
= 0; i
< sourceSize
; ++i
)
2522 if(sourceDataUC32
[i
] > nMax
)
2523 nMax
= sourceDataUC32
[i
];
2525 if(sourceDataUC32
[i
] < nMin
)
2526 nMin
= sourceDataUC32
[i
];
2529 Real32 fRange
= Real32(nMax
- nMin
);
2533 for(UInt32 i
= 0; i
< sourceSize
; ++i
)
2534 destDataUC16
[i
] = 0;
2538 for(UInt32 i
= 0; i
< sourceSize
; ++i
)
2539 destDataUC16
[i
] = UInt16
2541 (Real32(sourceDataUC32
[i
] - nMin
)) /
2547 case OSG_FLOAT32_IMAGEDATA
:
2548 for(UInt32 i
= 0; i
< sourceSize
; i
++)
2551 (Real32(sourceDataUC32
[i
])) / 4294967295.0;
2555 case OSG_FLOAT16_IMAGEDATA
:
2557 for (UInt32 i
= 0; i
< sourceSize
; i
++)
2560 (Real16(sourceDataUC32
[i
])) / REAL16_MAX
;
2565 FWARNING(("invalid destination data type \n"));
2570 case OSG_FLOAT32_IMAGEDATA
:
2572 switch(destDataType
)
2574 case OSG_UINT8_IMAGEDATA
:
2576 for(UInt32 i
= 0; i
< sourceSize
; i
++)
2578 destData
[i
] = UInt8(sourceDataF32
[i
]*255.0);
2582 case OSG_UINT16_IMAGEDATA
:
2584 for(UInt32 i
= 0; i
< sourceSize
; i
++)
2587 UInt16(sourceDataF32
[i
] * 65535.0);
2591 case OSG_UINT32_IMAGEDATA
:
2592 for(UInt32 i
= 0; i
< sourceSize
; i
++)
2595 UInt32(sourceDataF32
[i
] * 4294967295.0);
2599 case OSG_FLOAT16_IMAGEDATA
:
2601 for (UInt32 i
= 0; i
< sourceSize
; i
++)
2604 Real16(sourceDataF32
[i
]); // half-constructor
2609 FWARNING(("invalid destination data type \n"));
2614 case OSG_INT16_IMAGEDATA
:
2615 case OSG_INT32_IMAGEDATA
:
2617 FFATAL((" 'convertDataTypeTo' NYI\n "));
2622 FWARNING (( "invalid source data type \n"));
2626 if(dest
->getData() != NULL
)
2631 return (getData() ? true : false);
2634 /*! It just fills the hole image data with the given pixel value. It is
2635 mainly used to initialize the image data.
2638 void Image::clear(UChar8 pixelValue
)
2640 if(getData() != NULL
)
2641 memset(editData(), pixelValue
, getSize());
2644 void Image::clearFloat(Real32 pixelValue
)
2646 unsigned long n
= getSize()/getComponentSize();
2647 Real32
*d
= reinterpret_cast<Real32
*>(editData());
2658 void Image::clearHalf(Real16 pixelValue
)
2660 unsigned long n
= getSize()/getComponentSize();
2661 Real16
*d
= reinterpret_cast<Real16
*>(editData());
2668 /*-------------------------------------------------------------------------*/
2669 /* attachment handling */
2671 /*! returns true if the image has any attachments
2674 bool Image::hasAttachment(void) const
2676 Image
*img
=const_cast<Image
*>(this);
2678 ImageGenericAtt
*att
= dynamic_cast<ImageGenericAtt
*>(
2679 img
->Inherited::findAttachment(
2680 ImageGenericAtt::getClassType().getGroupId()));
2682 if(att
!= NULL
&& att
->getType().getNumFieldDescs() > 1)
2688 /*! returns the number of attachments
2691 UInt32
Image::attachmentCount(void) const
2693 Image
*img
= const_cast<Image
*>(this);
2695 ImageGenericAtt
*att
= dynamic_cast<ImageGenericAtt
*>(
2696 img
->Inherited::findAttachment(
2697 ImageGenericAtt::getClassType().getGroupId()));
2701 return att
->getType().getNumFieldDescs() - 1;
2709 /*! set a single string attachment for the given key/data pair
2712 void Image::setAttachmentField(const std::string
&key
,
2713 const std::string
&data
)
2715 ImageGenericAttUnrecPtr
att(dynamic_cast<ImageGenericAtt
*>(
2717 ImageGenericAtt::getClassType().getGroupId())));
2722 att
= ImageGenericAtt::create();
2729 FWARNING(("Image::setAttachmentField - can not create attachment\n"));
2734 EditFieldHandlePtr field
= att
->editDynamicFieldByName(key
.c_str());
2738 SFString::Description pDesc
= SFString::Description(
2739 SFString::getClassType(),
2745 Field::SFDefaultFlags
,
2746 static_cast<FieldIndexEditMethodSig
>(
2747 &ImageGenericAtt::editDynamicField
),
2748 static_cast<FieldIndexGetMethodSig
>(
2749 &ImageGenericAtt::getDynamicField
));
2752 UInt32 fieldId
= att
->addField(pDesc
);
2754 field
= att
->editDynamicField(fieldId
);
2757 SFString::EditHandlePtr strField
=
2758 boost::static_pointer_cast
<SFString::EditHandle
>(field
);
2760 if(strField
!= NULL
&& strField
->isValid() == true)
2761 (*strField
)->setValue(data
);
2764 /*! returns the string attachment for the given key or Null
2767 const std::string
*Image::findAttachmentField(const std::string
&key
) const
2769 Image
*img
=const_cast<Image
*>(this);
2771 ImageGenericAtt
*att
= dynamic_cast<ImageGenericAtt
*>(
2772 img
->findAttachment(
2773 ImageGenericAtt::getClassType().getGroupId()));
2777 GetFieldHandlePtr field
= att
->getDynamicFieldByName(key
.c_str());
2781 SFString::GetHandlePtr strField
=
2782 boost::static_pointer_cast
<SFString::GetHandle
>(field
);
2784 if(strField
!= NULL
&& strField
->isValid() == true)
2785 return &((*strField
)->getValue());
2792 /*! Method to scale the image. It just does a very simple but fast
2793 'nearest' scale. Should handle mipmap and frame data correct.
2794 The method can operate on the object or stores the result in
2795 the optional destination Image.
2798 bool Image::scale(Int32 width
,
2804 UInt32 sw
, sh
, sd
, dw
, dh
, dd
;
2805 Int32 frame
, side
, mipmap
;
2808 Int32 oldWidth
=getWidth();
2809 Int32 oldHeight
=getHeight();
2810 Int32 oldDepth
=getDepth();
2812 if ( (oldWidth
== width
) &&
2813 (oldHeight
== height
) &&
2814 (oldDepth
== depth
) )
2816 if(destination
!= NULL
)
2817 *destination
= *this;
2821 if (hasCompressedData())
2823 FFATAL (("Invalid Image::scale for compressed image\n"));
2827 if(destination
!= NULL
)
2829 destImage
= destination
;
2837 // !!!!!!!! WARNING WARNING !!!!!!!!!!!
2838 // !!!!!!!! Obscure copy of the old Image !!!!!!!!!!!
2839 const MFUInt8 srcPixel
= *getMFPixel();
2843 destImage
->set(PixelFormat(getPixelFormat()),
2855 // copy every mipmap in every side in every frame
2856 for(frame
= 0; frame
< getFrameCount(); frame
++)
2858 for (side
= 0; side
< getSideCount(); side
++)
2861 for(mipmap
= 0; mipmap
< getMipMapCount(); mipmap
++)
2863 // get the memory pointer
2864 src
= (&(srcPixel
[0])) +
2865 (side
* getSideSize ()) +
2866 (frame
* getFrameSize()) ;
2870 src
+= calcMipmapSumSize (mipmap
,
2876 dest
= destImage
->editData(mipmap
, frame
, side
);
2878 // calc the mipmap size
2879 sw
= oldWidth
>> mipmap
;
2880 sh
= oldHeight
>> mipmap
;
2881 sd
= oldDepth
>> mipmap
;
2883 destImage
->calcMipmapGeometry(mipmap
, dw
, dh
, dd
);
2885 // copy and scale the data
2886 scaleData(src
, sw
, sh
, sd
, dest
, dw
, dh
, dd
);
2895 /*! Mirror the image along horizontal, vertical, or depth.
2896 The method can operate on the object or stores the result in
2897 the optional destination Image.
2900 bool Image::mirror(bool horizontal
,
2905 if ( !horizontal
&& !vertical
)
2907 if(destination
!= NULL
)
2908 *destination
= *this;
2915 if(destination
!= NULL
)
2917 destImage
= destination
;
2925 // !!!!!!!! WARNING WARNING !!!!!!!!!!!
2926 // !!!!!!!! Obscure copy of the old Image !!!!!!!!!!!
2927 const MFUInt8 srcPixel
= (*getMFPixel());
2929 UInt32 width
= getWidth();
2930 UInt32 height
= getHeight();
2931 UInt32 depth
= getDepth();
2933 destImage
->set(PixelFormat(getPixelFormat()),
2945 Int32 frame
, side
, mipmap
;
2949 // copy every mipmap in every side in every frame
2950 for(frame
= 0; frame
< getFrameCount(); frame
++)
2952 for (side
= 0; side
< getSideCount(); side
++)
2954 for(mipmap
= 0; mipmap
< getMipMapCount(); mipmap
++)
2956 // get the memory pointer
2957 src
= (&(srcPixel
[0])) +
2958 (side
* getSideSize ()) +
2959 (frame
* getFrameSize());
2963 src
+= calcMipmapSumSize(mipmap
, width
, height
, depth
);
2966 dest
= destImage
->editData(mipmap
, frame
, side
);
2967 destImage
->calcMipmapGeometry(mipmap
, width
, height
, depth
);
2969 // copy and mirror the data
2970 mirrorData(src
, dest
, width
, height
, depth
, horizontal
,
2971 vertical
, flipDepth
);
2978 /*! Scale the image to the next power of 2 dimensions
2979 The method can operate on the object or stores the result in
2980 the optional destination Image.
2983 bool Image::scaleNextPower2(Image
*destination
)
2985 return scale(osgNextPower2(getWidth ()),
2986 osgNextPower2(getHeight()),
2987 osgNextPower2(getDepth ()),
2991 /*! Crop the image to the given bounding box.
2992 The method can operate on the object or stores the result in
2993 the optional destination Image.
2996 bool Image::subImage(Int32 offX
,
3004 ImageUnrecPtr
destImage(destination
);
3005 bool retCode
= true;
3007 if (hasCompressedData())
3009 FFATAL (("Invalid Image::subImage for compressed image\n"));
3013 if(destination
== NULL
)
3015 destImage
= Image::create();
3018 destImage
->set(PixelFormat(getPixelFormat()),
3028 const UChar8
*src
= getData ();
3029 UChar8
*dest
= destImage
->editData();
3031 FDEBUG(("Image::subImage (%d %d %d) - (%d %d %d) - destPtr %p\n",
3032 offX
, offY
, offZ
, destW
, destH
, destD
, dest
));
3034 // ensure destination data is zero
3035 memset(dest
, 0, destImage
->getSize());
3037 // determine the area to actually copy
3042 UInt32 xMax
= osgMin(getWidth (), offX
+ destW
);
3043 UInt32 yMax
= osgMin(getHeight(), offY
+ destH
);
3044 UInt32 zMax
= osgMin(getDepth (), offZ
+ destD
);
3046 // fill the destination buffer with the subdata
3049 for(UInt32 z
= zMin
; z
< zMax
; z
++)
3051 for(UInt32 y
= yMin
; y
< yMax
; y
++)
3053 for(UInt32 x
= xMin
; x
< xMax
; x
++)
3055 for(Int32 i
= 0; i
< getBpp(); i
++)
3057 dest
[destIdx
] = src
[((z
* getHeight() + y
) *
3058 getWidth() + x
) * getBpp() + i
];
3063 destIdx
+= (destW
- (xMax
- xMin
)) * getBpp();
3066 destIdx
+= (destH
- (yMax
- yMin
)) * destW
* getBpp();
3069 // rip the data from the local destImage if necessary
3070 if(destination
== NULL
)
3072 this->set(destImage
);
3079 The method can operate on the object or stores the result in
3080 the optional destination Image.
3083 bool Image::slice(Int32 offX
,
3088 ImageUnrecPtr
destImage(destination
);
3089 bool retCode
= true;
3092 if (hasCompressedData())
3094 FFATAL (("Invalid Image::slice for compressed image\n"));
3098 if(destination
== NULL
)
3100 destImage
= Image::create();
3103 FDEBUG(("Image::slice (%d %d %d)\n",
3117 FWARNING(("Image::slice - more/less than one non negative value\n"));
3124 retCode
= subImage(0,
3136 destImage
->set(PixelFormat(getPixelFormat()),
3146 const UChar8
*src
= getData ();
3147 UChar8
*dest
= destImage
->editData();
3149 // ensure destination data is zero
3150 memset(dest
, 0, destImage
->getSize());
3152 for(Int32 z
= 0; z
< getDepth(); z
++)
3154 for(Int32 x
= 0; x
< getWidth(); x
++)
3156 for(Int32 i
= 0; i
< getBpp(); i
++)
3158 dest
[(z
* getWidth() + x
) * getBpp() + i
] =
3159 src
[((z
* getHeight() + offY
) * getWidth() + x
) *
3169 destImage
->set(PixelFormat(getPixelFormat()),
3179 const UChar8
*src
= getData ();
3180 UChar8
*dest
= destImage
->editData();
3182 // ensure destination data is zero
3183 memset(dest
, 0, destImage
->getSize());
3185 for(Int32 z
= 0; z
< getDepth(); z
++)
3187 for(Int32 y
= 0; y
< getHeight(); y
++)
3189 for(Int32 i
= 0; i
< getBpp(); i
++)
3191 dest
[(z
* getHeight() + y
) * getBpp() + i
] =
3192 src
[((z
* getHeight() + y
) * getWidth() + offX
) *
3199 // rip the data from the local destImage if necessary
3200 if(destination
== NULL
)
3202 this->set(destImage
);
3208 /*! Create mipmaps data, level defines the number of level
3209 The method can operate on the object or stores the result in
3210 the optional destination Image.
3213 bool Image::createMipmap(Int32 level
, Image
*destination
)
3222 Offset offset
[][8] =
3225 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
3226 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3229 { 0, 0, 0 }, { 1, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
3230 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3233 { 0, 0, 0 }, { 0, 1, 0 }, { 0, 0, 0 }, { 0, 0, 0 },
3234 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3237 { 0, 0, 0 }, { 0, 1, 0 }, { 1, 0, 0 }, { 1, 1, 0 },
3238 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3241 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 0, 0 }, { 0, 0, 0 },
3242 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3245 { 0, 0, 0 }, { 1, 0, 0 }, { 0, 0, 1 }, { 1, 0, 1 },
3246 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3249 { 0, 0, 0 }, { 0, 0, 1 }, { 0, 1, 0 }, { 0, 1, 1 },
3250 { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }, { 0, 0, 0 }
3253 { 0, 0, 0 }, { 1, 0, 0 }, { 0, 1, 0 }, { 1, 1, 0 },
3254 { 0, 0, 1 }, { 1, 0, 1 }, { 0, 1, 1 }, { 1, 1, 1 }
3258 Int32 offsetSize
[] = { 0, 2, 2, 4, 2, 4, 4, 8 };
3260 ImageUnrecPtr
destImage(destination
);
3262 Int32 w
= getWidth(), h
= getHeight(), d
= getDepth();
3263 Int32 wm
, hm
, dm
, wi
, hi
, di
;
3267 const UInt16
*sourceDataUC16
;
3268 UInt16
*destDataUC16
;
3269 const UInt32
*sourceDataUC32
;
3270 UInt32
*destDataUC32
;
3271 const Real32
*sourceDataF32
;
3272 Real32
*destDataF32
;
3273 const Real16
*sourceDataH16
;
3274 Real16
*destDataH16
;
3276 if (hasCompressedData())
3278 FFATAL (("Invalid Image::createMipmap for compressed image\n"));
3282 if(destImage
== NULL
)
3284 destImage
= Image::create();
3288 Int32 value
, i
, elem
, dim
, side
, frame
, size
, mipmap
;
3289 Int32 channel
, lineSize
, sliceSize
;
3291 // calc the level count
3294 level
= calcMipmapLevelCount();
3297 // create destination image
3298 destImage
->set(getPixelFormat(),
3311 switch (getDataType())
3313 case OSG_UINT8_IMAGEDATA
:
3315 for(frame
= 0; frame
< getFrameCount(); frame
++)
3317 for(side
= 0; side
< getSideCount(); side
++)
3319 src
= this ->getData (0, frame
, side
);
3320 dest
= destImage
->editData(0, frame
, side
);
3322 size
= getWidth() * getHeight() * getDepth() * getBpp();
3324 memcpy(dest
, src
, size
);
3334 for(mipmap
= 1; mipmap
< level
; mipmap
++)
3336 lineSize
= w
* getBpp();
3337 sliceSize
= w
* h
* getBpp();
3339 wm
= (w
== 1) ? w
: (w
>> 1);
3340 hm
= (h
== 1) ? h
: (h
>> 1);
3341 dm
= (d
== 1) ? d
: (d
>> 1);
3343 dim
= (d
> dm
) * 1 + (h
> hm
) * 2 + (w
> wm
) * 4;
3345 elem
= offsetSize
[dim
];
3347 for(di
= 0; di
< dm
; di
++)
3349 for(hi
= 0; hi
< hm
; hi
++)
3351 for(wi
= 0; wi
< wm
; wi
++)
3353 for(channel
= 0; channel
< getBpp(); channel
++)
3357 for(i
= 0; i
< elem
; i
++)
3360 ((wi
* 2) + offset
[dim
][i
].w
) * getBpp() +
3361 ((hi
* 2) + offset
[dim
][i
].h
) * lineSize
+
3362 ((di
* 2) + offset
[dim
][i
].d
) * sliceSize
+
3366 *dest
++ = Int8(value
/ elem
);
3382 case OSG_UINT16_IMAGEDATA
:
3384 for(frame
= 0; frame
< getFrameCount(); frame
++)
3386 for(side
= 0; side
< getSideCount(); side
++)
3388 src
= this ->getData (0, frame
, side
);
3389 dest
= destImage
->editData(0, frame
, side
);
3391 size
= getWidth() * getHeight() * getDepth() * getBpp();
3393 memcpy(dest
, src
, size
);
3402 sourceDataUC16
= reinterpret_cast<const UInt16
*>(src
);
3403 destDataUC16
= reinterpret_cast< UInt16
*>(dest
);
3405 for(mipmap
= 1; mipmap
< level
; mipmap
++)
3407 lineSize
= w
* (getBpp() / getComponentSize());
3408 sliceSize
= w
* h
* (getBpp() / getComponentSize());
3410 wm
= (w
== 1) ? w
: (w
>> 1);
3411 hm
= (h
== 1) ? h
: (h
>> 1);
3412 dm
= (d
== 1) ? d
: (d
>> 1);
3414 dim
= (d
> dm
) * 1 + (h
> hm
) * 2 + (w
> wm
) * 4;
3416 elem
= offsetSize
[dim
];
3418 for(di
= 0; di
< dm
; di
++)
3420 for(hi
= 0; hi
< hm
; hi
++)
3422 for(wi
= 0; wi
< wm
; wi
++)
3425 channel
< (getBpp() / getComponentSize());
3430 for(i
= 0; i
< elem
; i
++)
3432 value
+= sourceDataUC16
[
3433 ((wi
* 2) + offset
[dim
][i
].w
) * (getBpp() / getComponentSize()) +
3434 ((hi
* 2) + offset
[dim
][i
].h
) * lineSize
+
3435 ((di
* 2) + offset
[dim
][i
].d
) * sliceSize
+
3439 *destDataUC16
++ = UInt16(value
/ elem
);
3445 sourceDataUC16
+= sliceSize
;
3455 case OSG_UINT32_IMAGEDATA
:
3457 for(frame
= 0; frame
< getFrameCount(); frame
++)
3459 for(side
= 0; side
< getSideCount(); side
++)
3461 src
= this ->getData (0, frame
,side
);
3462 dest
= destImage
->editData(0, frame
,side
);
3464 size
= getWidth() * getHeight() * getDepth() * getBpp();
3466 memcpy(dest
, src
, size
);
3475 sourceDataUC32
= reinterpret_cast<const UInt32
*>(src
);
3476 destDataUC32
= reinterpret_cast< UInt32
*>(dest
);
3478 for(mipmap
= 1; mipmap
< level
; mipmap
++)
3480 lineSize
= w
* (getBpp() / getComponentSize());
3481 sliceSize
= w
* h
* (getBpp() / getComponentSize());
3483 wm
= (w
== 1) ? w
: (w
>> 1);
3484 hm
= (h
== 1) ? h
: (h
>> 1);
3485 dm
= (d
== 1) ? d
: (d
>> 1);
3487 dim
= (d
> dm
) * 1 + (h
> hm
) * 2 + (w
> wm
) * 4;
3489 elem
= offsetSize
[dim
];
3491 for(di
= 0; di
< dm
; di
++)
3493 for(hi
= 0; hi
< hm
; hi
++)
3495 for(wi
= 0; wi
< wm
; wi
++)
3498 channel
< (getBpp()/getComponentSize());
3503 for(i
= 0; i
< elem
; i
++)
3505 value
+= (sourceDataUC32
[
3506 ((wi
* 2) + offset
[dim
][i
].w
) * (getBpp() / getComponentSize()) +
3507 ((hi
* 2) + offset
[dim
][i
].h
) * lineSize
+
3508 ((di
* 2) + offset
[dim
][i
].d
) * sliceSize
+
3511 *destDataUC32
++ = UInt32(value
);
3517 sourceDataUC32
+= sliceSize
;
3527 case OSG_FLOAT32_IMAGEDATA
:
3529 for(frame
= 0; frame
< getFrameCount(); frame
++)
3531 for(side
= 0; side
< getSideCount(); side
++)
3533 src
= this ->getData (0, frame
,side
);
3534 dest
= destImage
->editData(0, frame
,side
);
3536 size
= getWidth() * getHeight() * getDepth() * getBpp();
3538 memcpy(dest
, src
, size
);
3547 sourceDataF32
= reinterpret_cast<const Real32
*>(src
);
3548 destDataF32
= reinterpret_cast< Real32
*>(dest
);
3550 for(mipmap
= 1; mipmap
< level
; mipmap
++)
3552 lineSize
= w
* (getBpp() / getComponentSize());
3553 sliceSize
= w
* h
* (getBpp() / getComponentSize());
3555 wm
= (w
== 1) ? w
: (w
>> 1);
3556 hm
= (h
== 1) ? h
: (h
>> 1);
3557 dm
= (d
== 1) ? d
: (d
>> 1);
3559 dim
= (d
> dm
) * 1 + (h
> hm
) * 2 + (w
> wm
) * 4;
3561 elem
= offsetSize
[dim
];
3563 for(di
= 0; di
< dm
; di
++)
3565 for(hi
= 0; hi
< hm
; hi
++)
3567 for(wi
= 0; wi
< wm
; wi
++)
3570 channel
< (getBpp() / getComponentSize());
3575 for(i
= 0; i
< elem
; i
++)
3577 valueFloat
+= sourceDataF32
[
3578 ((wi
* 2) + offset
[dim
][i
].w
) * (getBpp() / getComponentSize()) +
3579 ((hi
* 2) + offset
[dim
][i
].h
) * lineSize
+
3580 ((di
* 2) + offset
[dim
][i
].d
) * sliceSize
+
3584 *destDataF32
++ = Real32(valueFloat
/ elem
);
3590 sourceDataF32
+= sliceSize
;
3600 case OSG_FLOAT16_IMAGEDATA
:
3601 for(frame
= 0; frame
< getFrameCount(); frame
++)
3603 for(side
= 0; side
< getSideCount(); side
++)
3605 src
= this->getData(0, frame
,side
);
3606 dest
= destImage
->editData(0, frame
,side
);
3607 size
= getWidth() * getHeight() * getDepth() * getBpp();
3608 memcpy(dest
,src
, size
);
3615 sourceDataH16
= reinterpret_cast<const Real16
*>(src
);
3616 destDataH16
= reinterpret_cast< Real16
*>(dest
);
3618 for(mipmap
= 1; mipmap
< level
; mipmap
++)
3620 lineSize
= w
* (getBpp() / getComponentSize());
3621 sliceSize
= w
* h
* (getBpp() / getComponentSize());
3622 wm
= (w
== 1) ? w
: (w
>> 1);
3623 hm
= (h
== 1) ? h
: (h
>> 1);
3624 dm
= (d
== 1) ? d
: (d
>> 1);
3626 dim
= (d
> dm
) * 1 + (h
> hm
) * 2 + (w
> wm
) * 4;
3627 elem
= offsetSize
[dim
];
3629 for(di
= 0; di
< dm
; di
++)
3631 for(hi
= 0; hi
< hm
; hi
++)
3633 for(wi
= 0; wi
< wm
; wi
++)
3635 for(channel
= 0; channel
< (getBpp()/getComponentSize()); channel
++)
3638 for(i
= 0; i
< elem
; i
++)
3640 valueFloat
+= sourceDataH16
[
3641 ((wi
* 2) + offset
[dim
][i
].w
) * (getBpp() / getComponentSize()) +
3642 ((hi
* 2) + offset
[dim
][i
].h
) * lineSize
+
3643 ((di
* 2) + offset
[dim
][i
].d
) * sliceSize
+
3646 *destDataH16
++ = Real16(valueFloat
/ elem
);
3651 sourceDataH16
+= sliceSize
;
3660 case OSG_INT16_IMAGEDATA
:
3661 case OSG_INT32_IMAGEDATA
:
3663 FFATAL((" 'createMipmap' NYI\n "));
3668 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
3672 // rip the data from the local destImage if necessary
3673 if(destination
== NULL
)
3675 this->set(destImage
);
3681 bool Image::removeMipmap(void)
3683 if(getMipMapCount() == 1) // no mipmaps nothing to do.
3686 // create destination image
3687 ImageUnrecPtr destImage
= Image::create();
3689 destImage
->set(getPixelFormat(),
3701 if(!destImage
->isValid())
3709 for(Int32 frame
= 0; frame
< getFrameCount(); frame
++)
3711 for(Int32 side
= 0; side
< getSideCount(); side
++)
3713 const UChar8
*src
= this->getData(0, frame
, side
);
3715 UChar8
*dest
= destImage
->editData(0, frame
, side
);
3717 Int32 size
= getWidth() * getHeight() * getDepth() * getBpp();
3719 memcpy(dest
,src
, size
);
3723 this->set(destImage
);
3730 /*! Write the image to the a file. The mimetype will be set automatically
3731 from the fileName suffix. Returns true on success.
3734 bool Image::write(const Char8
*fileName
)
3736 return ImageFileHandler::the()->write(this, fileName
);
3739 /*! Read the image data from a file. Returns true on success.
3742 bool Image::read(const Char8
*fileName
)
3744 return ImageFileHandler::the()->read(this, fileName
);
3748 /*! Store the image to the given mem block as 'mimeType'.
3749 mimeType can be 0, in which case the method will store the
3750 object as uncompressed mtd data.
3751 Returns the number of bytes used.
3754 UInt64
Image::store(const Char8
*mimeType
, UChar8
*mem
, Int32 memSize
)
3756 return ImageFileHandler::the()->store(this,
3762 /*! Restore the image from the given mem block. Returns the
3763 number of bytes used.
3766 UInt64
Image::restore(const UChar8
*mem
, Int32 memSize
)
3768 return ImageFileHandler::the()->restore(this, mem
, memSize
);
3772 /*-------------------------------------------------------------------------*/
3773 /* Constructor / Destructor */
3775 /*! Default Constructor. Creates a invalid Image of the size 0x0x0
3778 Image::Image(void) :
3786 /*! Copy Constructor. Creates a copy of the given image
3789 Image::Image(const Image
&obj
) :
3791 _mipmapOffset(obj
._mipmapOffset
),
3793 _hashValid (obj
._hashValid
)
3804 /*! Method to check, whether the object data defines a alpha channel or not
3807 bool Image::hasAlphaChannel(void)
3810 (getForceAlphaChannel() == true ) ||
3811 (getPixelFormat () == OSG_RGBA_PF
) ||
3812 (getPixelFormat () == OSG_BGRA_PF
) ||
3813 (getPixelFormat () == OSG_RGBA_DXT1
) ||
3814 (getPixelFormat () == OSG_RGBA_DXT3
) ||
3815 (getPixelFormat () == OSG_RGBA_DXT5
) ||
3816 (getPixelFormat () == OSG_A_PF
) ||
3817 (getPixelFormat () == OSG_I_PF
) ||
3818 (getPixelFormat () == OSG_LA_PF
) ||
3820 (getPixelFormat () == OSG_ALPHA_INTEGER_PF
) ||
3821 (getPixelFormat () == OSG_RGBA_INTEGER_PF
) ||
3822 (getPixelFormat () == OSG_BGRA_INTEGER_PF
) ||
3823 (getPixelFormat () == OSG_LUMINANCE_ALPHA_INTEGER_PF
);
3826 /*! Method to check, whether the alpha channel is just fully transparent/
3829 bool Image::isAlphaBinary(void)
3832 (getForceAlphaBinary() == true ) ||
3833 (getPixelFormat () == OSG_RGBA_DXT1
);
3836 /*! Method to check, whether the data is compressed
3838 bool Image::hasCompressedData(void)
3841 (getForceCompressedData() == true ) ||
3842 (getPixelFormat () == OSG_RGB_DXT1
) ||
3843 (getPixelFormat () == OSG_RGBA_DXT1
) ||
3844 (getPixelFormat () == OSG_RGBA_DXT3
) ||
3845 (getPixelFormat () == OSG_RGBA_DXT5
);
3849 /*! Method to check, whether the object data defines a color channel or not
3851 bool Image::hasColorChannel(void)
3854 ( !( getPixelFormat() == OSG_A_PF
||
3855 getPixelFormat() == OSG_I_PF
||
3856 getPixelFormat() == OSG_L_PF
||
3857 getPixelFormat() == OSG_LA_PF
||
3859 getPixelFormat() == OSG_ALPHA_INTEGER_PF
||
3860 getPixelFormat() == OSG_LUMINANCE_ALPHA_INTEGER_PF
)) ||
3861 getForceColorChannel();
3864 /*! Method returns the right frame data for the given time.
3867 const UInt8
*Image::getDataByTime(Time time
, UInt32
) const
3869 UInt32 frameNum
= calcFrameNum(time
, true);
3871 return getData(0, frameNum
);
3874 UInt8
*Image::editDataByTime(Time time
, UInt32
)
3876 UInt32 frameNum
= calcFrameNum(time
, true);
3878 return editData(0, frameNum
);
3881 /*! Check all the alpha values to see if they're 0 or 1, return true if they
3882 are, false if no alpha or intermediate values. No Alpha channel is considered
3886 bool Image::calcIsAlphaBinary(void)
3888 if(!hasAlphaChannel() || getPixelFormat() == OSG_RGBA_DXT1
)
3891 if(getPixelFormat() == OSG_RGBA_DXT3
|| getPixelFormat() == OSG_RGBA_DXT5
)
3893 FWARNING(("Image::calcIsAlphaBinary: not implemenetd for DXT3 "
3894 "and DXT5 yet, assuming false.\n"));
3898 UInt32 npix
= getWidth() * getHeight() * getDepth() * getFrameCount();
3899 UInt8 pixelsize
= getBpp();
3901 const UInt8
*data
= getData();
3903 switch(getPixelFormat())
3906 data
+= getComponentSize(); break;
3909 data
+= getComponentSize() * 3; break;
3911 FWARNING(("Image::calcIsAlphaBinary: found unknown "
3912 "image format %x, assumning false.\n",
3917 switch(getDataType())
3919 case OSG_UINT8_IMAGEDATA
:
3920 for(; npix
> 0; --npix
, data
+= pixelsize
)
3922 if(*data
!= 0 && *data
!= 0xffU
)
3926 case OSG_UINT16_IMAGEDATA
:
3927 for(; npix
> 0; --npix
, data
+= pixelsize
)
3929 const UInt16
*d
= reinterpret_cast<const UInt16
*>(data
);
3930 if(*d
!= 0 && *d
!= 0xffffU
)
3934 case OSG_UINT32_IMAGEDATA
:
3935 for(; npix
> 0; --npix
, data
+= pixelsize
)
3937 const UInt32
*d
= reinterpret_cast<const UInt32
*>(data
);
3938 if(*d
!= 0 && *d
!= 0xffffffffU
)
3942 case OSG_FLOAT16_IMAGEDATA
:
3943 for(; npix
> 0; --npix
, data
+= pixelsize
)
3945 const Real16
*d
= reinterpret_cast<const Real16
*>(data
);
3946 if(*d
!= 0 && *d
!= 1)
3950 case OSG_FLOAT32_IMAGEDATA
:
3951 for(; npix
> 0; --npix
, data
+= pixelsize
)
3953 const Real32
*d
= reinterpret_cast<const Real32
*>(data
);
3954 if(*d
!= 0 && *d
!= 1)
3958 case OSG_INT16_IMAGEDATA
:
3959 case OSG_INT32_IMAGEDATA
:
3961 FFATAL((" 'calcIsAlphaBinary' NYI\n "));
3966 FWARNING(("Image::calcIsAlphaBinary: found unknown "
3967 "data type %d, assumning false.\n",
3975 /*! Method which returns the frame number for the given time
3977 UInt32
Image::calcFrameNum(Time time
, bool OSG_CHECK_ARG(loop
)) const
3979 UInt64 frameNum
= ((getFrameDelay() > 0) && (getFrameCount() > 0)) ?
3980 (UInt64(time
/ getFrameDelay()) % getFrameCount()) : 0;
3982 return ((frameNum
> 0) ? UInt32(frameNum
) : 0);
3985 /*! Internal used method to calculate the next mipmap geo for the given level
3987 void Image::calcMipmapGeometry(UInt32 mipmapNum
,
3990 UInt32
&depth
) const
3992 width
= getWidth() ? osgMax(getWidth () >> mipmapNum
, 1) : 0 ;
3993 height
= getHeight() ? osgMax(getHeight() >> mipmapNum
, 1) : 0 ;
3994 depth
= getDepth() ? osgMax(getDepth () >> mipmapNum
, 1) : 0 ;
3998 #pragma set woff 1209
4001 /*! Internal used method to calculate the number of mipmaps levels
4003 UInt32
Image::calcMipmapLevelCount(void) const
4005 UInt32 w
= getWidth(), h
= getHeight(), d
= getDepth();
4008 for (level
= 1; true; level
++)
4010 if ((w
== 1) && (h
== 1) && (d
== 1))
4016 w
= (w
>>= 1) ? w
: 1;
4017 h
= (h
>>= 1) ? h
: 1;
4018 d
= (d
>>= 1) ? d
: 1;
4025 #pragma reset woff 1209
4028 /*-------------------------------------------------------------------------*/
4029 /* Calculate Mipmap Size */
4031 /*! Method to calculate the mem sum of a mipmap level in byte
4033 UInt32
Image::calcMipmapLevelSize ( UInt32 mipmapNum
,
4034 UInt32 w
, UInt32 h
, UInt32 d
) const
4038 switch (getPixelFormat())
4042 sum
= (((w
?w
:1)+3)/4) * (((h
?h
:1)+3)/4) * 8;
4046 sum
= (((w
?w
:1)+3)/4) * (((h
?h
:1)+3)/4) * 16;
4049 sum
= (w
?w
:1) * (h
?h
:1) * getBpp();
4058 /*! Internal used method to calculate the size in bpp of a single mipmap
4059 level for the current image settings
4062 UInt32
Image::calcMipmapLevelSize(UInt32 mipmapNum
) const
4065 calcMipmapGeometry(mipmapNum
, w
, h
, d
);
4066 return calcMipmapLevelSize(mipmapNum
, w
, h
, d
);
4069 /*! Internal used method to calculate the mem sum of all mipmap levels in bpp
4072 UInt32
Image::calcMipmapSumSize(UInt32 mipmapNum
,
4083 sum
+= calcMipmapLevelSize(mipmapNum
,w
,h
,d
);
4094 /*! Method to calculate the mem sum of all mipmap levels in byte
4095 for the current Image paramter
4097 UInt32
Image::calcMipmapSumSize (UInt32 mipmapNum
) const
4099 return calcMipmapSumSize(mipmapNum
, getWidth(), getHeight(), getDepth());
4102 /*-------------------------------------------------------------------------*/
4105 /*! Internal method to set the data and update related properties.
4108 bool Image::createData(const UInt8
*data
, bool allocMem
)
4111 Int32 mapSizeFormat
= sizeof(_formatDic
) / sizeof(UInt32
[2]);
4112 Int32 mapSizeType
= sizeof(_typeDic
) / sizeof(UInt32
[2]);
4114 UInt32 byteCount
= 0;
4117 UInt32 pixelFormat
= 0;
4118 UInt32 typeFormat
= 0;
4120 for(i
= 0; i
< mapSizeFormat
; i
++)
4122 if(_formatDic
[i
][0] == getPixelFormat())
4124 pixelFormat
= _formatDic
[i
][1];
4129 for(i
= 0; i
< mapSizeType
; i
++)
4131 if(_typeDic
[i
][0] == getDataType())
4133 typeFormat
= _typeDic
[i
][1];
4138 setComponentSize(typeFormat
);
4139 setBpp (pixelFormat
* typeFormat
);
4146 if(getHeight() == 1)
4161 UInt32 mipmapSumSize
= calcMipmapSumSize(getMipMapCount());
4162 setSideSize (mipmapSumSize
);
4165 setFrameSize(getSideSize() * getSideCount());
4169 if(allocMem
&& (byteCount
= getSize()))
4171 if(getMFPixel()->size() != byteCount
)
4175 if(byteCount
< getMFPixel()->size())
4177 editMFPixel()->clear();
4178 // free unused memory.
4180 tmp
.swap(*editMFPixel());
4182 editMFPixel()->resize(byteCount
);
4186 FFATAL(("Image::createData : Couldn't allocate %u bytes!\n",
4195 memcpy(editData(), data
, byteCount
);
4200 editMFPixel()->clear();
4203 return (getData() != NULL
);
4206 /*! Internal method to scale image data blocks
4208 bool Image::scaleData(const UInt8
*srcData
,
4217 Real32 sx
= Real32(srcW
) / Real32(destW
);
4218 Real32 sy
= Real32(srcH
) / Real32(destH
);
4219 Real32 sz
= Real32(srcD
) / Real32(destD
);
4221 Int32 srcSize
= srcW
* srcH
* srcD
* getBpp();
4223 // Int32 destDize = destW * destH * destD;
4226 const UInt8
*pSlice
;
4228 const UInt8
*pPixel
;
4230 if(destW
== srcW
&& destH
== srcH
&& destD
== srcD
)
4232 // same size, just copy
4233 memcpy(destData
, srcData
, srcSize
);
4236 { // different size, to 'nearest' copy
4237 for(z
= 0; z
< destD
; z
++)
4239 pSlice
= srcData
+ int(sz
* z
) * getBpp() * srcW
* srcH
;
4241 for(y
= 0; y
< destH
; y
++)
4243 pLine
= pSlice
+ int(sy
* y
) * getBpp() * srcW
;
4245 for(x
= 0; x
< destW
; x
++)
4247 pPixel
= pLine
+ int(sx
* x
) * getBpp();
4253 *destData
++ = *pPixel
++;
4263 void Image::calcMipmapOffsets(void)
4265 UInt32 mipMapCount
= getMipMapCount();
4267 if(mipMapCount
== 0)
4270 _mipmapOffset
.resize(mipMapCount
);
4273 for(UInt32 i=0;i<mipMapCount;++i)
4274 _mipmapOffset[i] = calcMipmapSumSize[i];
4279 UInt32 w
= getWidth ();
4280 UInt32 h
= getHeight();
4281 UInt32 d
= getDepth ();
4283 _mipmapOffset
[0] = 0;
4285 for(UInt32 i
=1;i
<mipMapCount
;++i
)
4287 sum
+= calcMipmapLevelSize(i
,w
,h
,d
);
4289 _mipmapOffset
[i
] = sum
;
4297 void Image::calcHash(void) const
4301 boost::hash_range(_hash
, _mfPixel
.begin(), _mfPixel
.end());
4305 /*! Internal method to mirror image data blocks
4307 bool Image::mirrorData(const UInt8
*srcData
,
4316 int dx_step
= horizontal
? -1 : 1;
4317 int dx_start
= horizontal
? width
-1 : 0;
4318 int dy_step
= vertical
? -1 : 1;
4319 int dy_start
= vertical
? height
-1 : 0;
4320 int dz_step
= flipDepth
? -1 : 1;
4321 int dz_start
= flipDepth
? depth
-1 : 0;
4324 for(int sz
= 0; sz
< depth
; sz
++, dz
+= dz_step
)
4326 const UInt8
*src_slice
= srcData
+ (sz
* getBpp() * width
* height
);
4327 UInt8
*dst_slice
= destData
+ (dz
* getBpp() * width
* height
);
4329 for(int sy
= 0; sy
< height
; sy
++, dy
+= dy_step
)
4331 const UInt8
*src_line
= src_slice
+ (sy
* getBpp() * width
);
4332 UInt8
*dst_line
= dst_slice
+ (dy
* getBpp() * width
);
4334 for(int sx
= 0; sx
< width
; sx
++, dx
+= dx_step
)
4336 const UInt8
*src_pixel
= src_line
+ (sx
* getBpp());
4337 UInt8
*dst_pixel
= dst_line
+ (dx
* getBpp());
4343 *dst_pixel
++ = *src_pixel
++;
4351 /*! Assign operator. Does a copy of the given Image object.
4354 Image
&Image::operator=(const Image
&image
)
4356 this->set(PixelFormat(image
.getPixelFormat()),
4360 image
.getMipMapCount(),
4361 image
.getFrameCount (),
4362 image
.getFrameDelay (),
4364 image
.getDataType (),
4366 image
.getSideCount ());
4371 /*! Less operator; compares the data sizes of the two images
4373 bool Image::operator<(const Image
&image
)
4375 return (getSize() < image
.getSize()) ? true : false;
4378 /*! Method to compare the object to another Image instance;
4379 Checks first all parameter and afterwards the Image data;
4382 bool Image::operator ==(const Image
&image
)
4384 unsigned long i
, s
= getSize();
4386 if((getWidth () == image
.getWidth ()) &&
4387 (getHeight () == image
.getHeight ()) &&
4388 (getDepth () == image
.getDepth ()) &&
4389 (getMipMapCount() == image
.getMipMapCount()) &&
4390 (getFrameCount () == image
.getFrameCount ()) &&
4391 (getFrameDelay () == image
.getFrameDelay ()) &&
4392 (getPixelFormat() == image
.getPixelFormat()) &&
4393 (getDataType () == image
.getDataType ()) &&
4394 (getSideCount () == image
.getSideCount ()))
4397 for(i
= 0; i
< s
; ++i
)
4399 if(image
.getData()[i
] != getData()[i
])
4407 /*! Method to compare the object to another Image instance;
4408 Checks first all parameter and afterwards the Image data;
4411 bool Image::operator !=(const Image
&image
)
4413 return !(*this == image
);
4417 /*! Explicitly notfies parents about a change of the image contents. This is
4418 not strictly required because they are notified anyways, but can be used
4419 for optimization by specifying only the area that has actually changed.
4421 \note Currently only TextureChunks are notified.
4423 \warning Successive calls to this function will overwrite the previously
4424 set dirty area. If an application makes changes to multiple regions
4425 they have to accumulated by the user before calling this function.
4428 Image::imageContentChanged(
4429 Int32 minX
, Int32 maxX
, Int32 minY
, Int32 maxY
, Int32 minZ
, Int32 maxZ
)
4431 MFFieldContainerPtr::iterator parentsIt
= _mfParents
.begin();
4432 MFFieldContainerPtr::iterator parentsEnd
= _mfParents
.end ();
4434 for(; parentsIt
!= parentsEnd
; ++parentsIt
)
4436 TextureChunkPtr texParent
= TextureChunkPtr::dcast(*parentsIt
);
4438 if(texParent
!= NullFC
)
4440 texParent
->imageContentChanged(minX
, maxX
, minY
, maxY
, minZ
, maxZ
);