fixed: gcc8 compile issues
[opensg.git] / Source / System / Image / OSGImage.cpp
blob160d2002956c05b70e5e1ecbae8e63a261e08433
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 \*---------------------------------------------------------------------------*/
39 #if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
40 #pragma GCC diagnostic warning "-Wsign-compare"
41 #endif
43 #ifdef WIN32
44 #pragma warning( disable : 4018 )
45 #endif
47 //---------------------------------------------------------------------------
48 // Includes
49 //---------------------------------------------------------------------------
51 #define OSG_COMPILEIMAGE
53 #include <cstdlib>
54 #include <cstdio>
56 #include <algorithm>
57 #include <boost/functional/hash/hash.hpp>
59 #include "OSGConfig.h"
60 #include "OSGLog.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"
72 #include "OSGImage.h"
74 OSG_BEGIN_NAMESPACE
76 /*! \class OSG::Image
77 1D/2D/3D Image with various pixel types data, can also optional hold
78 mipMap and simple multi-frame data.
81 /*------------------------------------------------------------------------*/
82 /* static member */
84 /*! Static dictionary to map pixelData values to the bytes per pixel
85 (bpp) value.
86 Internaly used in the createData() method.
89 UInt32 Image::_formatDic[][2] =
91 { OSG_A_PF, 1 },
92 { OSG_I_PF, 1 },
93 { OSG_L_PF, 1 },
94 { OSG_LA_PF, 2 },
95 { OSG_R_PF, 1 },
96 { OSG_RG_PF, 2 },
97 { OSG_RGB_PF, 3 },
98 { OSG_RGBA_PF, 4 },
99 { OSG_BGR_PF, 3 },
100 { OSG_BGRA_PF, 4 },
101 { OSG_RGB_DXT1, 3 },
102 { OSG_RGBA_DXT1, 4 },
103 { OSG_RGBA_DXT3, 4 },
104 { OSG_RGBA_DXT5, 4 },
105 { OSG_DEPTH_PF, 1 },
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,
139 UInt32 origin,
140 BitVector details)
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,
153 whichField);
155 ++parentsIt;
158 if(0x0000 != (whichField & DataTypeFieldMask))
160 // Update internals
161 Int32 mapSizeType = sizeof(_typeDic) / sizeof(UInt32[2]);
162 UInt32 typeFormat = 0;
163 Int32 i;
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 |
177 WidthFieldMask |
178 HeightFieldMask |
179 DepthFieldMask |
180 PixelFormatFieldMask )))
182 setSideSize(calcMipmapSumSize(_sfMipMapCount.getValue()));
185 if(0x0000 != (whichField & (SideSizeFieldMask | SideCountFieldMask)))
187 setFrameSize(_sfSideSize.getValue() * _sfSideCount.getValue());
190 calcMipmapOffsets();
192 _hashValid = false;
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())
207 case OSG_A_PF:
208 pfStr = "ALPHA";
209 break;
210 case OSG_I_PF:
211 pfStr = "INTENSITY";
212 break;
213 case OSG_L_PF:
214 pfStr = "LUMINANCE";
215 break;
216 case OSG_LA_PF:
217 pfStr = "LUMINANCE_ALPHA";
218 break;
219 case OSG_BGR_PF:
220 pfStr = "BGR";
221 break;
222 case OSG_BGRA_PF:
223 pfStr = "BGRA";
224 break;
225 case OSG_R_PF:
226 pfStr = "RED";
227 break;
228 case OSG_RG_PF:
229 pfStr = "RG";
230 break;
231 case OSG_RGB_PF:
232 pfStr = "RGB";
233 break;
234 case OSG_RGBA_PF:
235 pfStr = "RGBA";
236 break;
237 case OSG_RGB_DXT1:
238 pfStr = "RGB_DXT1";
239 break;
240 case OSG_RGBA_DXT1:
241 pfStr = "RGBA_DXT1";
242 break;
243 case OSG_RGBA_DXT3:
244 pfStr = "RGBA_DXT3";
245 break;
246 case OSG_RGBA_DXT5:
247 pfStr = "RGBA_DXT5";
248 break;
249 case OSG_DEPTH_PF:
250 pfStr = "DEPTH";
251 break;
252 case OSG_DEPTH_STENCIL_PF:
253 pfStr = "DEPTH_STENCIL";
254 break;
255 case OSG_ALPHA_INTEGER_PF:
256 pfStr = "ALPHA_INTEGER";
257 break;
258 case OSG_RGB_INTEGER_PF:
259 pfStr = "RGB_INTEGER";
260 break;
261 case OSG_RGBA_INTEGER_PF:
262 pfStr = "RGBA_INTEGER";
263 break;
264 case OSG_BGR_INTEGER_PF:
265 pfStr = "BGR_INTEGER";
266 break;
267 case OSG_BGRA_INTEGER_PF:
268 pfStr = "BGRA_INTEGER";
269 break;
270 case OSG_LUMINANCE_INTEGER_PF:
271 pfStr = "LUMINANCE_INTEGER";
272 break;
273 case OSG_LUMINANCE_ALPHA_INTEGER_PF:
274 pfStr = "LUMINANCE_ALPHA_INTEGER";
275 break;
276 default:
277 pfStr = "UNKNOWN_PIXEL_FORMAT";
278 break;
281 switch (getDataType())
283 case OSG_UINT8_IMAGEDATA:
284 typeStr = "IMAGEDATA_TYPE UCHAR8";
285 break;
286 case OSG_UINT16_IMAGEDATA:
287 typeStr = "IMAGEDATA_TYPE UCHAR16";
288 break;
289 case OSG_UINT32_IMAGEDATA:
290 typeStr = "IMAGEDATA_TYPE UCHAR32";
291 break;
292 case OSG_FLOAT16_IMAGEDATA:
293 typeStr = "IMAGEDATA_TYPE FLOAT16";
294 break;
295 case OSG_FLOAT32_IMAGEDATA:
296 typeStr = "IMAGEDATA_TYPE FLOAT32";
297 break;
298 case OSG_INT16_IMAGEDATA:
299 typeStr = "IMAGEDATA_TYPE INT16";
300 break;
301 case OSG_INT32_IMAGEDATA:
302 typeStr = "IMAGEDATA_TYPE INT32";
303 break;
304 case OSG_UINT24_8_IMAGEDATA:
305 typeStr = "IMAGEDATA_TYPE UINT24_8";
306 break;
308 default:
309 typeStr = "UNKNOWN_IMAGEDATA_TYPE";
310 break;
313 FLOG (("ImageDump: %s; %d/%d/%d; #mm: %d, side %d, #frame: %d, "
314 "frameDelay %g, dataType %s, size: %ld\n",
315 pfStr,
316 getWidth(),
317 getHeight(),
318 getDepth(),
319 getMipMapCount(),
320 getSideCount(),
321 getFrameCount(),
322 getFrameDelay(),
323 typeStr,
324 getSize()));
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()));
342 return 0;
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,
351 Int32 width,
352 Int32 height,
353 Int32 depth,
354 Int32 mipmapCount,
355 Int32 frameCount,
356 Time frameDelay,
357 const UInt8 *data,
358 Int32 type,
359 bool allocMem,
360 Int32 sidecount )
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);
374 setDataType (type );
376 calcMipmapOffsets();
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(),
389 image->getWidth (),
390 image->getHeight (),
391 image->getDepth (),
392 image->getMipMapCount(),
393 image->getFrameCount (),
394 image->getFrameDelay (),
395 image->getData (),
396 image->getDataType (),
397 true,
398 image->getSideCount ());
399 return true;
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)
408 if(da)
410 createData(da);
412 else
414 FWARNING(("Image::setData(Null) call\n"));
417 return (da ? true : false);
420 void Image::clearData(void)
422 editMFPixel()->clear();
423 // free unused memory.
424 MFUInt8 tmp;
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,
432 Int32 offY,
433 Int32 offZ,
434 Int32 srcW,
435 Int32 srcH,
436 Int32 srcD,
437 const UInt8 *src )
439 UChar8 *dest = editData();
440 UInt64 lineSize;
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"));
448 return false;
451 if(!src || !dest)
453 FFATAL(("Invalid data pointer in Image::setSubData\n"));
454 return false;
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();
483 return true;
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;
494 Int32 value;
496 if((getMipMapCount() == 1) &&
497 ((getFrameCount() == 1) || (getDepth() == 1)))
499 value = getFrameCount();
501 setFrameCount(getDepth());
502 setDepth (value );
504 retCode = true;
506 else
508 FWARNING (("Cant flipDepthFrameData(); invalid data layout\n"));
511 return retCode;
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;
522 Int64 j;
523 Int64 v;
525 bool isHead = strchr(value, ' ') ? true : false;
527 if (hasCompressedData())
529 FFATAL (("Invalid Image::addValue for compressed image\n"));
530 return false;
533 // make sure we only read one image at a time
534 if(currentImage == this)
536 if(isHead)
538 FDEBUG(("Start new read cycle in image::addValue()\n"));
541 else
543 if(!isHead)
545 FFATAL(("Additional image date for different image\n"));
549 currentImage = this;
551 if(isHead == true)
553 Int32 width;
554 Int32 height;
555 Int32 pixelDepth;
556 PixelFormat pf = Image::OSG_INVALID_PF;
558 // read the head
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:
567 switch(pixelDepth)
569 case 1:
570 pf = OSG::Image::OSG_L_PF;
571 break;
572 case 2:
573 pf = OSG::Image::OSG_LA_PF;
574 break;
575 case 3:
576 pf = OSG::Image::OSG_RGB_PF;
577 break;
578 case 4:
579 pf = OSG::Image::OSG_RGBA_PF;
580 break;
581 default:
582 pf = OSG::Image::OSG_INVALID_PF;
583 FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
584 break;
586 break;
588 case OSG_UINT16_IMAGEDATA:
589 switch(pixelDepth)
591 case 2:
592 pf = OSG::Image::OSG_L_PF;
593 break;
594 case 4:
595 pf = OSG::Image::OSG_LA_PF;
596 break;
597 case 6:
598 pf = OSG::Image::OSG_RGB_PF;
599 break;
600 case 8:
601 pf = OSG::Image::OSG_RGBA_PF;
602 break;
603 default:
604 pf = OSG::Image::OSG_INVALID_PF;
605 FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
606 break;
608 break;
610 case OSG_UINT32_IMAGEDATA:
611 switch(pixelDepth)
613 case 4:
614 pf = OSG::Image::OSG_L_PF;
615 break;
616 case 8:
617 pf = OSG::Image::OSG_LA_PF;
618 break;
619 case 12:
620 pf = OSG::Image::OSG_RGB_PF;
621 break;
622 case 16:
623 pf = OSG::Image::OSG_RGBA_PF;
624 break;
625 default:
626 pf = OSG::Image::OSG_INVALID_PF;
627 FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
628 break;
630 break;
632 case OSG_FLOAT32_IMAGEDATA:
633 switch(pixelDepth)
635 case 4:
636 pf = OSG::Image::OSG_L_PF;
637 break;
638 case 8:
639 pf = OSG::Image::OSG_LA_PF;
640 break;
641 case 12:
642 pf = OSG::Image::OSG_RGB_PF;
643 break;
644 case 16:
645 pf = OSG::Image::OSG_RGBA_PF;
646 break;
647 default:
648 pf = OSG::Image::OSG_INVALID_PF;
649 FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
650 break;
652 break;
654 case OSG_FLOAT16_IMAGEDATA:
655 switch(pixelDepth)
657 case 2:
658 pf = OSG::Image::OSG_L_PF;
659 break;
660 case 4:
661 pf = OSG::Image::OSG_LA_PF;
662 break;
663 case 6:
664 pf = OSG::Image::OSG_RGB_PF;
665 break;
666 case 8:
667 pf = OSG::Image::OSG_RGBA_PF;
668 break;
669 default:
670 pf = OSG::Image::OSG_INVALID_PF;
671 FFATAL(("Invalid pixel depth: %d\n", pixelDepth));
672 break;
674 break;
676 case OSG_INT16_IMAGEDATA:
677 case OSG_INT32_IMAGEDATA:
679 FFATAL((" 'addValue' NYI\n "));
681 break;
683 default:
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();
694 else
696 currentData = NULL;
699 else
701 if(currentData != NULL)
703 // add data
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,
723 Image *destination,
724 Int32 iCompressionFlags)
726 UChar8 *data = NULL;
727 const UChar8 *sourceData = NULL;
728 UInt32 srcI, destI, destSize = 0;
729 UInt32 sum;
730 Real64 sumReal;
731 ImageUnrecPtr dest(destination);
733 if (hasCompressedData())
735 FFATAL (("Invalid Image::reformat for compressed image\n"));
736 return false;
739 if(destination == NULL)
741 dest = Image::create();
744 FINFO(("Try to reformat image from pixelDepth %d to %d\n",
745 getPixelFormat(),
746 pixelFormat ));
748 if(iCompressionFlags == 0)
750 iCompressionFlags = (osgsquish::kColourMetricPerceptual |
751 osgsquish::kColourRangeFit );
754 iCompressionFlags &= ~0x07;
756 // TODO !!! code all the cases !!!
758 if(getSize() != 0 &&
759 pixelFormat != OSG_INVALID_PF &&
760 (destination != 0 || (pixelFormat != static_cast<Image::PixelFormat>(getPixelFormat()))))
763 dest->set(pixelFormat,
764 getWidth (),
765 getHeight (),
766 getDepth (),
767 getMipMapCount(),
768 getFrameCount (),
769 getFrameDelay (),
770 NULL,
771 getDataType (),
772 true,
773 getSideCount ());
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);
800 if(data)
802 switch (getPixelFormat())
804 //-----------------------------------------------------
805 case OSG_A_PF:
806 switch (pixelFormat)
808 case OSG_A_PF:
809 case OSG_I_PF:
810 case OSG_L_PF:
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);
819 break;
821 default:
822 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
823 break;
825 break;
827 case OSG_LA_PF:
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++];
836 break;
837 case OSG_UINT16_IMAGEDATA:
838 for (srcI = destI = 0; destI < destSize/getComponentSize();)
840 destDataUC16[destI++] = sourceDataUC16[srcI];
841 destDataUC16[destI++] = sourceDataUC16[srcI++];
843 break;
844 case OSG_UINT32_IMAGEDATA:
845 for (srcI = destI = 0; destI < destSize/getComponentSize();)
847 destDataUC32[destI++] = sourceDataUC32[srcI];
848 destDataUC32[destI++] = sourceDataUC32[srcI++];
850 break;
851 case OSG_FLOAT32_IMAGEDATA:
852 for (srcI = destI = 0; destI < destSize/getComponentSize();)
854 destDataF32[destI++] = sourceDataF32[srcI];
855 destDataF32[destI++] = sourceDataF32[srcI++];
857 break;
859 case OSG_FLOAT16_IMAGEDATA:
860 for (srcI = destI = 0; destI < destSize/getComponentSize();)
862 destDataH16[destI++] = sourceDataH16[srcI];
863 destDataH16[destI++] = sourceDataH16[srcI++];
865 break;
866 default:
867 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
868 break;
870 break;
872 case OSG_RGB_PF:
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++];
882 break;
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++];
890 break;
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++];
898 break;
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++];
906 break;
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++];
914 break;
915 default:
916 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
917 break;
919 break;
921 case OSG_RGBA_PF:
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++];
932 break;
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++];
941 break;
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++];
950 break;
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++];
959 break;
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++];
968 break;
969 default:
970 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
971 break;
973 break;
974 default:
975 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
976 break;
978 break;
980 //-----------------------------------------------------
981 case OSG_I_PF:
982 switch (pixelFormat)
984 case OSG_A_PF:
985 case OSG_I_PF:
986 case OSG_L_PF:
987 switch (getDataType())
989 case OSG_UINT8_IMAGEDATA:
990 memcpy (data, getData(), destSize);
991 break;
992 case OSG_UINT16_IMAGEDATA:
993 memcpy (data, getData(), destSize);
994 break;
995 case OSG_UINT32_IMAGEDATA:
996 memcpy (data, getData(), destSize);
997 break;
998 case OSG_FLOAT32_IMAGEDATA:
999 memcpy (data, getData(), destSize);
1000 break;
1001 case OSG_FLOAT16_IMAGEDATA:
1002 memcpy (data, getData(), destSize);
1003 break;
1005 default:
1006 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1007 break;
1009 break;
1011 case OSG_LA_PF:
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++];
1020 break;
1021 case OSG_UINT16_IMAGEDATA:
1022 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1024 destDataUC16[destI++] = sourceDataUC16[srcI];
1025 destDataUC16[destI++] = sourceDataUC16[srcI++];
1027 break;
1028 case OSG_UINT32_IMAGEDATA:
1029 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1031 destDataUC32[destI++] = sourceDataUC32[srcI];
1032 destDataUC32[destI++] = sourceDataUC32[srcI++];
1034 break;
1035 case OSG_FLOAT32_IMAGEDATA:
1036 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1038 destDataF32[destI++] = sourceDataF32[srcI];
1039 destDataF32[destI++] = sourceDataF32[srcI++];
1041 break;
1043 case OSG_FLOAT16_IMAGEDATA:
1044 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1046 destDataH16[destI++] = sourceDataH16[srcI];
1047 destDataH16[destI++] = sourceDataH16[srcI++];
1049 break;
1050 default:
1051 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1052 break;
1054 break;
1056 case OSG_RGB_PF:
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++];
1066 break;
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++];
1074 break;
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++];
1082 break;
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++];
1090 break;
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++];
1098 break;
1099 default:
1100 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1101 break;
1103 break;
1105 case OSG_RGBA_PF:
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++];
1116 break;
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++];
1125 break;
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++];
1134 break;
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++];
1143 break;
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++];
1152 break;
1153 default:
1154 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1155 break;
1157 break;
1158 default:
1159 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1160 break;
1162 break;
1165 //-----------------------------------------------------
1166 case OSG_L_PF:
1167 switch (pixelFormat)
1169 case OSG_A_PF:
1170 case OSG_I_PF:
1171 case OSG_L_PF:
1172 switch (getDataType())
1174 case OSG_UINT8_IMAGEDATA:
1175 memcpy (data, getData(), destSize);
1176 break;
1177 case OSG_UINT16_IMAGEDATA:
1178 memcpy (data, getData(), destSize);
1179 break;
1180 case OSG_UINT32_IMAGEDATA:
1181 memcpy (data, getData(), destSize);
1182 break;
1183 case OSG_FLOAT32_IMAGEDATA:
1184 memcpy (data, getData(), destSize);
1185 break;
1186 case OSG_FLOAT16_IMAGEDATA:
1187 memcpy (data, getData(), destSize);
1188 break;
1190 default:
1191 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1192 break;
1194 break;
1196 case OSG_LA_PF:
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++];
1205 break;
1206 case OSG_UINT16_IMAGEDATA:
1207 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1209 destDataUC16[destI++] = sourceDataUC16[srcI];
1210 destDataUC16[destI++] = sourceDataUC16[srcI++];
1212 break;
1213 case OSG_UINT32_IMAGEDATA:
1214 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1216 destDataUC32[destI++] = sourceDataUC32[srcI];
1217 destDataUC32[destI++] = sourceDataUC32[srcI++];
1219 break;
1220 case OSG_FLOAT32_IMAGEDATA:
1221 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1223 destDataF32[destI++] = sourceDataF32[srcI];
1224 destDataF32[destI++] = sourceDataF32[srcI++];
1226 break;
1228 case OSG_FLOAT16_IMAGEDATA:
1229 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1231 destDataH16[destI++] = sourceDataH16[srcI];
1232 destDataH16[destI++] = sourceDataH16[srcI++];
1234 break;
1235 default:
1236 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1237 break;
1239 break;
1241 case OSG_RGB_PF:
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++];
1251 break;
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++];
1259 break;
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++];
1267 break;
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++];
1275 break;
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++];
1283 break;
1284 default:
1285 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1286 break;
1288 break;
1290 case OSG_RGBA_PF:
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++];
1301 break;
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++];
1310 break;
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++];
1319 break;
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++];
1328 break;
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++];
1337 break;
1338 default:
1339 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1340 break;
1342 break;
1343 default:
1344 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1345 break;
1347 break;
1349 //-----------------------------------------------------
1350 case OSG_LA_PF:
1351 switch (pixelFormat)
1353 case OSG_A_PF:
1354 switch (getDataType())
1356 case OSG_UINT8_IMAGEDATA:
1357 for (srcI = destI = 0; destI < destSize;)
1359 srcI++;
1360 data[destI++] = sourceData[srcI++];
1362 break;
1363 case OSG_UINT16_IMAGEDATA:
1364 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1366 srcI++;
1367 destDataUC16[destI++] = sourceDataUC16[srcI++];
1369 break;
1370 case OSG_UINT32_IMAGEDATA:
1371 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1373 srcI++;
1374 destDataUC32[destI++] = sourceDataUC32[srcI++];
1376 break;
1377 case OSG_FLOAT32_IMAGEDATA:
1378 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1380 srcI++;
1381 destDataF32[destI++] = sourceDataF32[srcI++];
1383 break;
1384 case OSG_FLOAT16_IMAGEDATA:
1385 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1387 srcI++;
1388 destDataH16[destI++] = sourceDataH16[srcI++];
1390 break;
1391 default:
1392 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1393 break;
1395 break;
1396 case OSG_I_PF:
1397 case OSG_L_PF:
1398 switch (getDataType())
1400 case OSG_UINT8_IMAGEDATA:
1401 for (srcI = destI = 0; destI < destSize;)
1403 data[destI++] = sourceData[srcI++];
1404 srcI++;
1406 break;
1407 case OSG_UINT16_IMAGEDATA:
1408 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1410 destDataUC16[destI++] = sourceDataUC16[srcI++];
1411 srcI++;
1413 break;
1414 case OSG_UINT32_IMAGEDATA:
1415 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1417 destDataUC32[destI++] = sourceDataUC32[srcI++];
1418 srcI++;
1420 break;
1421 case OSG_FLOAT32_IMAGEDATA:
1422 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1424 destDataF32[destI++] = sourceDataF32[srcI++];
1425 srcI++;
1427 break;
1428 case OSG_FLOAT16_IMAGEDATA:
1429 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1431 destDataH16[destI++] = sourceDataH16[srcI++];
1432 srcI++;
1434 break;
1435 default:
1436 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1437 break;
1439 break;
1440 case OSG_LA_PF:
1441 switch (getDataType())
1443 case OSG_UINT8_IMAGEDATA:
1444 memcpy (data, getData(), destSize);
1445 break;
1446 case OSG_UINT16_IMAGEDATA:
1447 memcpy (data, getData(), destSize);
1448 break;
1449 case OSG_UINT32_IMAGEDATA:
1450 memcpy (data, getData(), destSize);
1451 break;
1452 case OSG_FLOAT32_IMAGEDATA:
1453 memcpy (data, getData(), destSize);
1454 break;
1455 case OSG_FLOAT16_IMAGEDATA:
1456 memcpy (data, getData(), destSize);
1457 break;
1458 default:
1459 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1460 break;
1462 break;
1464 case OSG_RGB_PF:
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++];
1473 srcI++;
1475 break;
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++];
1482 srcI++;
1484 break;
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++];
1491 srcI++;
1493 break;
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++];
1500 srcI++;
1502 break;
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++];
1509 srcI++;
1511 break;
1512 default:
1513 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1514 break;
1516 break;
1518 case OSG_RGBA_PF:
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++];
1529 break;
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++];
1538 break;
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++];
1547 break;
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++];
1556 break;
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++];
1565 break;
1566 default:
1567 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1568 break;
1570 break;
1571 default:
1572 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
1573 break;
1575 break;
1577 //-----------------------------------------------------
1578 case OSG_RGB_PF:
1579 switch (pixelFormat)
1581 case OSG_A_PF:
1582 case OSG_I_PF:
1583 case OSG_L_PF:
1584 switch (getDataType())
1586 case OSG_UINT8_IMAGEDATA:
1587 for (srcI = destI = 0; destI < destSize;)
1589 sum = 0;
1590 sum += sourceData[srcI++];
1591 sum += sourceData[srcI++];
1592 sum += sourceData[srcI++];
1593 data[destI++] = sum / 3;
1595 break;
1596 case OSG_UINT16_IMAGEDATA:
1597 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1599 sum = 0;
1600 sum += sourceDataUC16[srcI++];
1601 sum += sourceDataUC16[srcI++];
1602 sum += sourceDataUC16[srcI++];
1603 destDataUC16[destI++] = sum / 3;
1605 break;
1606 case OSG_UINT32_IMAGEDATA:
1607 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1609 sum = 0;
1610 sum += sourceDataUC32[srcI++];
1611 sum += sourceDataUC32[srcI++];
1612 sum += sourceDataUC32[srcI++];
1613 destDataUC32[destI++] = sum / 3;
1615 break;
1616 case OSG_FLOAT32_IMAGEDATA:
1617 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1619 sumReal = 0;
1620 sumReal += sourceDataF32[srcI++];
1621 sumReal += sourceDataF32[srcI++];
1622 sumReal += sourceDataF32[srcI++];
1623 destDataF32[destI++] = sumReal / 3.0;
1625 break;
1626 case OSG_FLOAT16_IMAGEDATA:
1627 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1629 sumReal = 0;
1630 sumReal += sourceDataH16[srcI++];
1631 sumReal += sourceDataH16[srcI++];
1632 sumReal += sourceDataH16[srcI++];
1633 destDataH16[destI++] = sumReal / 3.0;
1635 break;
1636 default:
1637 FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
1638 break;
1640 break;
1641 case OSG_LA_PF:
1642 switch (getDataType())
1644 case OSG_UINT8_IMAGEDATA:
1645 for (srcI = destI = 0; destI < destSize;)
1647 sum = 0;
1648 sum += sourceData[srcI++];
1649 sum += sourceData[srcI++];
1650 sum += sourceData[srcI++];
1651 data[destI++] = sum / 3;
1652 data[destI++] = sum / 3;
1654 break;
1655 case OSG_UINT16_IMAGEDATA:
1656 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1658 sum = 0;
1659 sum += sourceDataUC16[srcI++];
1660 sum += sourceDataUC16[srcI++];
1661 sum += sourceDataUC16[srcI++];
1662 destDataUC16[destI++] = sum / 3;
1663 destDataUC16[destI++] = sum / 3;
1665 break;
1666 case OSG_UINT32_IMAGEDATA:
1667 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1669 sum = 0;
1670 sum += sourceDataUC32[srcI++];
1671 sum += sourceDataUC32[srcI++];
1672 sum += sourceDataUC32[srcI++];
1673 destDataUC32[destI++] = sum / 3;
1674 destDataUC32[destI++] = sum / 3;
1676 break;
1677 case OSG_FLOAT32_IMAGEDATA:
1678 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1680 sumReal = 0;
1681 sumReal += sourceDataF32[srcI++];
1682 sumReal += sourceDataF32[srcI++];
1683 sumReal += sourceDataF32[srcI++];
1684 destDataF32[destI++] = sumReal / 3.0;
1685 destDataF32[destI++] = sumReal / 3.0;
1687 break;
1688 case OSG_FLOAT16_IMAGEDATA:
1689 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1691 sumReal = 0;
1692 sumReal += sourceDataH16[srcI++];
1693 sumReal += sourceDataH16[srcI++];
1694 sumReal += sourceDataH16[srcI++];
1695 destDataH16[destI++] = sumReal / 3.0;
1696 destDataH16[destI++] = sumReal / 3.0;
1698 break;
1699 default:
1700 FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
1701 break;
1703 break;
1704 case OSG_RGB_PF:
1705 switch (getDataType())
1707 case OSG_UINT8_IMAGEDATA:
1708 memcpy (data, getData(), destSize);
1709 break;
1710 case OSG_UINT16_IMAGEDATA:
1711 memcpy (data, getData(), destSize);
1712 break;
1713 case OSG_UINT32_IMAGEDATA:
1714 memcpy (data, getData(), destSize);
1715 break;
1716 case OSG_FLOAT32_IMAGEDATA:
1717 memcpy (data, getData(), destSize);
1718 break;
1719 case OSG_FLOAT16_IMAGEDATA:
1720 memcpy (data, getData(), destSize);
1721 break;
1722 default:
1723 FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
1724 break;
1726 break;
1728 case OSG_RGBA_PF:
1729 switch (getDataType())
1731 case OSG_UINT8_IMAGEDATA:
1732 for (srcI = destI = 0; destI < destSize;)
1734 sum = 0;
1735 sum += data[destI++] = sourceData[srcI++];
1736 sum += data[destI++] = sourceData[srcI++];
1737 sum += data[destI++] = sourceData[srcI++];
1738 data[destI++] = sum / 3;
1740 break;
1741 case OSG_UINT16_IMAGEDATA:
1742 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1744 sum = 0;
1745 sum += destDataUC16[destI++] = sourceDataUC16[srcI++];
1746 sum += destDataUC16[destI++] = sourceDataUC16[srcI++];
1747 sum += destDataUC16[destI++] = sourceDataUC16[srcI++];
1748 destDataUC16[destI++] = sum / 3;
1750 break;
1751 case OSG_UINT32_IMAGEDATA:
1752 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1754 sum = 0;
1755 sum += destDataUC32[destI++] = sourceDataUC32[srcI++];
1756 sum += destDataUC32[destI++] = sourceDataUC32[srcI++];
1757 sum += destDataUC32[destI++] = sourceDataUC32[srcI++];
1758 destDataUC32[destI++] = sum / 3;
1760 break;
1761 case OSG_FLOAT32_IMAGEDATA:
1762 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1764 sumReal = 0;
1765 sumReal += destDataF32[destI++] = sourceDataF32[srcI++];
1766 sumReal += destDataF32[destI++] = sourceDataF32[srcI++];
1767 sumReal += destDataF32[destI++] = sourceDataF32[srcI++];
1768 destDataF32[destI++] = sumReal / 3.0;
1770 break;
1771 case OSG_FLOAT16_IMAGEDATA:
1772 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1774 sumReal = 0;
1775 sumReal += destDataH16[destI++] = sourceDataH16[srcI++];
1776 sumReal += destDataH16[destI++] = sourceDataH16[srcI++];
1777 sumReal += destDataH16[destI++] = sourceDataH16[srcI++];
1778 destDataH16[destI++] = sumReal / 3.0;
1780 break;
1781 default:
1782 FWARNING (( "RGB: Invalid source IMAGE_DATA_TYPE\n" ));
1783 break;
1785 break;
1786 #if defined(GL_COMPRESSED_RGB_S3TC_DXT1_EXT)
1787 case OSG_RGB_DXT1:
1789 iCompressionFlags |= osgsquish::kDxt1;
1791 #ifdef OSG_DEBUG
1792 Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
1793 getHeight(),
1794 iCompressionFlags);
1796 OSG_ASSERT(iStorage == Int32(destSize));
1797 #endif
1799 osgsquish::CompressImage(sourceData,
1800 255,
1801 getWidth (),
1802 getHeight(),
1803 data,
1804 iCompressionFlags);
1806 break;
1807 #endif
1808 #if defined(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
1809 case OSG_RGBA_DXT1:
1811 iCompressionFlags |= osgsquish::kDxt1;
1813 #ifdef OSG_DEBUG
1814 Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
1815 getHeight(),
1816 iCompressionFlags);
1818 OSG_ASSERT(iStorage == Int32(destSize));
1819 #endif
1821 osgsquish::CompressImage(sourceData,
1822 255,
1823 getWidth (),
1824 getHeight(),
1825 data,
1826 iCompressionFlags);
1828 break;
1829 #endif
1830 #if defined(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
1831 case OSG_RGBA_DXT3:
1833 iCompressionFlags |= osgsquish::kDxt3;
1835 #ifdef OSG_DEBUG
1836 Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
1837 getHeight(),
1838 iCompressionFlags);
1840 OSG_ASSERT(iStorage == Int32(destSize));
1841 #endif
1843 osgsquish::CompressImage(sourceData,
1844 255,
1845 getWidth (),
1846 getHeight(),
1847 data,
1848 iCompressionFlags);
1850 break;
1851 #endif
1852 #if defined(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
1853 case OSG_RGBA_DXT5:
1855 iCompressionFlags |= osgsquish::kDxt5;
1857 #ifdef OSG_DEBUG
1858 Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
1859 getHeight(),
1860 iCompressionFlags);
1862 OSG_ASSERT(iStorage == Int32(destSize));
1863 #endif
1865 osgsquish::CompressImage(sourceData,
1866 255,
1867 getWidth (),
1868 getHeight(),
1869 data,
1870 iCompressionFlags);
1872 break;
1873 #endif
1875 default:
1876 FWARNING (( "RGB: Invalid target IMAGE_DATA_TYPE\n" ));
1877 break;
1879 break;
1882 //-----------------------------------------------------
1883 case OSG_RGBA_PF:
1885 switch (pixelFormat)
1887 case OSG_A_PF:
1888 switch (getDataType())
1890 case OSG_UINT8_IMAGEDATA:
1891 for (srcI = destI = 0; destI < destSize;)
1893 srcI += 3;
1894 data[destI++] = sourceData[srcI++];;
1896 break;
1897 case OSG_UINT16_IMAGEDATA:
1898 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1900 srcI += 3;
1901 destDataUC16[destI++] = sourceDataUC16[srcI++];;
1903 break;
1904 case OSG_UINT32_IMAGEDATA:
1905 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1907 srcI += 3;
1908 destDataUC32[destI++] = sourceDataUC32[srcI++];;
1910 break;
1911 case OSG_FLOAT32_IMAGEDATA:
1912 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1914 srcI += 3;
1915 destDataF32[destI++] = sourceDataF32[srcI++];
1917 break;
1918 case OSG_FLOAT16_IMAGEDATA:
1919 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1921 srcI += 3;
1922 destDataH16[destI++] = sourceDataH16[srcI++];
1924 break;
1925 default:
1926 FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
1927 break;
1929 break;
1931 case OSG_I_PF:
1932 case OSG_L_PF:
1933 switch (getDataType())
1935 case OSG_UINT8_IMAGEDATA:
1936 for (srcI = destI = 0; destI < destSize;)
1938 sum = 0;
1939 sum += sourceData[srcI++];
1940 sum += sourceData[srcI++];
1941 sum += sourceData[srcI++];
1942 data[destI++] = sum / 3;
1943 srcI++;
1945 break;
1946 case OSG_UINT16_IMAGEDATA:
1947 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1949 sum = 0;
1950 sum += sourceDataUC16[srcI++];
1951 sum += sourceDataUC16[srcI++];
1952 sum += sourceDataUC16[srcI++];
1953 destDataUC16[destI++] = sum / 3;
1954 srcI++;
1956 break;
1957 case OSG_UINT32_IMAGEDATA:
1958 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1960 sum = 0;
1961 sum += sourceDataUC32[srcI++];
1962 sum += sourceDataUC32[srcI++];
1963 sum += sourceDataUC32[srcI++];
1964 destDataUC32[destI++] = sum / 3;
1965 srcI++;
1967 break;
1968 case OSG_FLOAT32_IMAGEDATA:
1969 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1971 sumReal = 0;
1972 sumReal += sourceDataF32[srcI++];
1973 sumReal += sourceDataF32[srcI++];
1974 sumReal += sourceDataF32[srcI++];
1975 destDataF32[destI++] = sumReal / 3.0;
1976 srcI++;
1978 break;
1979 case OSG_FLOAT16_IMAGEDATA:
1980 for (srcI = destI = 0; destI < destSize/getComponentSize();)
1982 sumReal = 0;
1983 sumReal += sourceDataH16[srcI++];
1984 sumReal += sourceDataH16[srcI++];
1985 sumReal += sourceDataH16[srcI++];
1986 destDataH16[destI++] = sumReal / 3.0;
1987 srcI++;
1989 break;
1990 default:
1991 FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
1992 break;
1994 break;
1996 case OSG_LA_PF:
1997 switch (getDataType())
1999 case OSG_UINT8_IMAGEDATA:
2000 for (srcI = destI = 0; destI < destSize;)
2002 sum = 0;
2003 sum += sourceData[srcI++];
2004 sum += sourceData[srcI++];
2005 sum += sourceData[srcI++];
2006 data[destI++] = sum / 3;
2007 data[destI++] = sourceData[srcI++];;
2009 break;
2010 case OSG_UINT16_IMAGEDATA:
2011 for (srcI = destI = 0; destI < destSize/getComponentSize();)
2013 sum = 0;
2014 sum += sourceDataUC16[srcI++];
2015 sum += sourceDataUC16[srcI++];
2016 sum += sourceDataUC16[srcI++];
2017 destDataUC16[destI++] = sum / 3;
2018 destDataUC16[destI++] = sourceDataUC16[srcI++];;
2020 break;
2021 case OSG_UINT32_IMAGEDATA:
2022 for (srcI = destI = 0; destI < destSize/getComponentSize();)
2024 sum = 0;
2025 sum += sourceDataUC32[srcI++];
2026 sum += sourceDataUC32[srcI++];
2027 sum += sourceDataUC32[srcI++];
2028 destDataUC32[destI++] = sum / 3;
2029 destDataUC32[destI++] = sourceDataUC32[srcI++];;
2031 break;
2032 case OSG_FLOAT32_IMAGEDATA:
2033 for (srcI = destI = 0; destI < destSize/getComponentSize();)
2035 sumReal = 0;
2036 sumReal += sourceDataF32[srcI++];
2037 sumReal += sourceDataF32[srcI++];
2038 sumReal += sourceDataF32[srcI++];
2039 destDataF32[destI++] = sumReal / 3.0;
2040 destDataF32[destI++] = sourceDataF32[srcI++];
2042 break;
2043 case OSG_FLOAT16_IMAGEDATA:
2044 for (srcI = destI = 0; destI < destSize/getComponentSize();)
2046 sumReal = 0;
2047 sumReal += sourceDataH16[srcI++];
2048 sumReal += sourceDataH16[srcI++];
2049 sumReal += sourceDataH16[srcI++];
2050 destDataH16[destI++] = sumReal / 3.0;
2051 destDataH16[destI++] = sourceDataH16[srcI++];
2053 break;
2054 default:
2055 FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
2056 break;
2058 break;
2060 case OSG_RGB_PF:
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++];
2069 srcI++;
2071 break;
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++];
2078 srcI++;
2080 break;
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++];
2087 srcI++;
2089 break;
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++];
2096 srcI++;
2098 break;
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++];
2105 srcI++;
2107 break;
2108 default:
2109 FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
2110 break;
2112 break;
2114 case OSG_RGBA_PF:
2115 switch (getDataType())
2117 case OSG_UINT8_IMAGEDATA:
2118 memcpy (data, getData(), destSize);
2119 break;
2120 case OSG_UINT16_IMAGEDATA:
2121 memcpy (data, getData(), destSize);
2122 break;
2123 case OSG_UINT32_IMAGEDATA:
2124 memcpy (data, getData(), destSize);
2125 break;
2126 case OSG_FLOAT32_IMAGEDATA:
2127 memcpy (data, getData(), destSize);
2128 break;
2129 case OSG_FLOAT16_IMAGEDATA:
2130 memcpy (data, getData(), destSize);
2131 break;
2132 default:
2133 FWARNING (( "RGBA: Invalid source IMAGE_DATA_TYPE\n" ));
2134 break;
2136 break;
2138 #if defined(GL_COMPRESSED_RGBA_S3TC_DXT1_EXT)
2139 case OSG_RGBA_DXT1:
2141 iCompressionFlags |= osgsquish::kDxt1;
2143 #ifdef OSG_DEBUG
2144 Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
2145 getHeight(),
2146 iCompressionFlags);
2148 OSG_ASSERT(iStorage == Int32(destSize));
2149 #endif
2151 osgsquish::CompressImage(sourceData,
2152 getWidth (),
2153 getHeight(),
2154 data,
2155 iCompressionFlags);
2157 break;
2158 #endif
2159 #if defined(GL_COMPRESSED_RGBA_S3TC_DXT3_EXT)
2160 case OSG_RGBA_DXT3:
2162 iCompressionFlags |= osgsquish::kDxt3;
2164 #ifdef OSG_DEBUG
2165 Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
2166 getHeight(),
2167 iCompressionFlags);
2169 OSG_ASSERT(iStorage == Int32(destSize));
2170 #endif
2172 osgsquish::CompressImage(sourceData,
2173 getWidth (),
2174 getHeight(),
2175 data,
2176 iCompressionFlags);
2178 break;
2179 #endif
2180 #if defined(GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
2181 case OSG_RGBA_DXT5:
2183 iCompressionFlags |= osgsquish::kDxt5;
2185 #ifdef OSG_DEBUG
2186 Int32 iStorage = osgsquish::GetStorageRequirements(getWidth(),
2187 getHeight(),
2188 iCompressionFlags);
2190 OSG_ASSERT(iStorage == Int32(destSize));
2191 #endif
2193 osgsquish::CompressImage(sourceData,
2194 getWidth (),
2195 getHeight(),
2196 data,
2197 iCompressionFlags);
2199 break;
2200 #endif
2202 default:
2203 break;
2205 break;
2208 case OSG_DEPTH_PF:
2209 #if defined(GL_DEPTH_STENCIL_EXT) || defined(GL_DEPTH_STENCIL_NV)
2210 case OSG_DEPTH_STENCIL_PF:
2211 #endif
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:
2219 case OSG_R_PF:
2220 case OSG_RG_PF:
2222 FFATAL((" 'reformat' NYI\n "));
2224 break;
2226 default:
2227 FWARNING (( "Unvalid pixeldepth (%d) in reformat() !\n",
2228 pixelFormat ));
2231 if (data)
2233 // rip the data from the local destImage if necessary
2234 if(destination == NULL)
2236 this->set(dest);
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:
2257 // do nothing
2258 break;
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));
2268 break;
2270 case OSG_UINT32_IMAGEDATA:
2272 for(UInt32 i=0;i<size;++i)
2274 UInt32 p = dataUC32[i];
2276 dataUC32[i] =
2277 (((p & 0x000000FF) << 24) | ((p & 0x0000FF00) << 8) |
2278 ((p & 0x00FF0000) >> 8) | ((p & 0xFF000000) >> 24) );
2281 break;
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]);
2293 dataF32[i] = p;
2295 break;
2297 case OSG_INT16_IMAGEDATA:
2298 case OSG_INT32_IMAGEDATA:
2300 FFATAL((" 'swapDataEndian' NYI\n "));
2302 break;
2304 default:
2305 FWARNING (( "invalid source data type \n"));
2306 break;
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"));
2320 return false;
2323 if(destDataType == getDataType())
2325 FWARNING (( "source image and destination image have same data "
2326 "types: no conversion possible"));
2327 return true;
2330 FINFO(("Try to convert image from dataType %d to %d\n",
2331 getDataType(), destDataType));
2333 ImageUnrecPtr dest;
2335 dest = Image::create();
2337 dest->set(getPixelFormat(),
2338 getWidth (),
2339 getHeight (),
2340 getDepth (),
2341 getMipMapCount(),
2342 getFrameCount (),
2343 0.0,
2345 destDataType,
2346 true,
2347 getSideCount() );
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);
2375 break;
2377 case OSG_UINT32_IMAGEDATA:
2379 for (UInt32 i = 0; i < sourceSize; i++)
2381 destDataUC32[i] = UInt32(sourceData[i]<<24);
2383 break;
2385 case OSG_FLOAT32_IMAGEDATA:
2387 for (UInt32 i = 0; i < sourceSize; i++)
2389 destDataF32[i] = Real32(sourceData[i]/255.0);
2391 break;
2393 case OSG_FLOAT16_IMAGEDATA:
2395 for (UInt32 i = 0; i < sourceSize; i++)
2397 destDataH16[i] = Real16(sourceData[i]/255.0);
2399 break;
2401 default:
2402 FWARNING (( "invalid destination data type \n" ));
2403 break;
2406 break;
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);
2428 if (fRange <= 0.0)
2430 for(UInt32 i = 0; i < sourceSize; ++i)
2431 destData[i] = 0;
2433 else
2435 for(UInt32 i = 0; i < sourceSize; ++i)
2437 destData[i] = UInt8
2438 (255.0 *
2439 (Real32 (sourceDataUC16[i] - nMin)) /
2440 fRange) ;
2444 break;
2446 case OSG_UINT32_IMAGEDATA:
2448 for (UInt32 i = 0; i < sourceSize; i++)
2450 destDataUC32[i] = UInt32(sourceDataUC16[i]<<16);
2452 break;
2454 case OSG_FLOAT32_IMAGEDATA:
2456 for (UInt32 i = 0; i < sourceSize; i++)
2458 destDataF32[i] = Real32(sourceDataUC16[i]/65535.0);
2461 break;
2463 case OSG_FLOAT16_IMAGEDATA:
2465 for (UInt32 i = 0; i < sourceSize; i++)
2467 destDataH16[i] = Real16(sourceDataUC16[i]/255.0);
2469 break;
2471 default:
2472 FWARNING (( "invalid destination data type \n" ));
2473 break;
2475 break;
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);
2497 if (fRange <= 0.0)
2499 for(UInt32 i = 0; i < sourceSize; ++i)
2500 destData[i] = 0;
2502 else
2504 for(UInt32 i = 0; i < sourceSize; ++i)
2506 destData[i] = UInt8
2507 (255.0 *
2508 (Real32(sourceDataUC32[i] - nMin)) /
2509 fRange );
2513 break;
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);
2531 if(fRange <= 0.0)
2533 for(UInt32 i = 0; i < sourceSize; ++i)
2534 destDataUC16[i] = 0;
2536 else
2538 for(UInt32 i = 0; i < sourceSize; ++i)
2539 destDataUC16[i] = UInt16
2540 (65535.0 *
2541 (Real32(sourceDataUC32[i] - nMin)) /
2542 fRange);
2545 break;
2547 case OSG_FLOAT32_IMAGEDATA:
2548 for(UInt32 i = 0; i < sourceSize; i++)
2550 destDataF32[i] =
2551 (Real32(sourceDataUC32[i])) / 4294967295.0;
2553 break;
2555 case OSG_FLOAT16_IMAGEDATA:
2557 for (UInt32 i = 0; i < sourceSize; i++)
2559 destDataH16[i] =
2560 (Real16(sourceDataUC32[i])) / REAL16_MAX;
2562 break;
2564 default:
2565 FWARNING(("invalid destination data type \n"));
2566 break;
2568 break;
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);
2580 break;
2582 case OSG_UINT16_IMAGEDATA:
2584 for(UInt32 i = 0; i < sourceSize; i++)
2586 destDataUC16[i] =
2587 UInt16(sourceDataF32[i] * 65535.0);
2589 break;
2591 case OSG_UINT32_IMAGEDATA:
2592 for(UInt32 i = 0; i < sourceSize; i++)
2594 destDataUC32[i] =
2595 UInt32(sourceDataF32[i] * 4294967295.0);
2597 break;
2599 case OSG_FLOAT16_IMAGEDATA:
2601 for (UInt32 i = 0; i < sourceSize; i++)
2603 destDataH16[i] =
2604 Real16(sourceDataF32[i]); // half-constructor
2606 break;
2608 default:
2609 FWARNING(("invalid destination data type \n"));
2610 break;
2612 break;
2614 case OSG_INT16_IMAGEDATA:
2615 case OSG_INT32_IMAGEDATA:
2617 FFATAL((" 'convertDataTypeTo' NYI\n "));
2619 break;
2621 default:
2622 FWARNING (( "invalid source data type \n"));
2623 break;
2626 if(dest->getData() != NULL)
2628 this->set(dest);
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());
2649 if(n && d)
2651 while(n--)
2653 *d++ = pixelValue;
2658 void Image::clearHalf(Real16 pixelValue)
2660 unsigned long n = getSize()/getComponentSize();
2661 Real16 *d = reinterpret_cast<Real16 *>(editData());
2663 if(n && d)
2664 while(n--)
2665 *d++ = pixelValue;
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)
2683 return true;
2684 else
2685 return false;
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()));
2699 if(att != NULL)
2701 return att->getType().getNumFieldDescs() - 1;
2703 else
2705 return 0;
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 *>(
2716 findAttachment(
2717 ImageGenericAtt::getClassType().getGroupId())));
2720 if(att == NULL)
2722 att = ImageGenericAtt::create();
2724 addAttachment(att);
2727 if(att == NULL)
2729 FWARNING(("Image::setAttachmentField - can not create attachment\n"));
2731 return;
2734 EditFieldHandlePtr field = att->editDynamicFieldByName(key.c_str());
2736 if(field == NULL)
2738 SFString::Description pDesc = SFString::Description(
2739 SFString::getClassType(),
2740 key.c_str(),
2744 true,
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()));
2775 if(att != NULL)
2777 GetFieldHandlePtr field = att->getDynamicFieldByName(key.c_str());
2779 if(field != NULL)
2781 SFString::GetHandlePtr strField =
2782 boost::static_pointer_cast<SFString::GetHandle>(field);
2784 if(strField != NULL && strField->isValid() == true)
2785 return &((*strField)->getValue());
2789 return NULL;
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,
2799 Int32 height,
2800 Int32 depth,
2801 Image *destination)
2803 Image *destImage;
2804 UInt32 sw, sh, sd, dw, dh, dd;
2805 Int32 frame, side, mipmap;
2806 const UChar8 *src;
2807 UChar8 *dest;
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;
2819 return true;
2821 if (hasCompressedData())
2823 FFATAL (("Invalid Image::scale for compressed image\n"));
2824 return false;
2827 if(destination != NULL)
2829 destImage = destination;
2831 else
2833 destImage = this;
2836 // get pixel
2837 // !!!!!!!! WARNING WARNING !!!!!!!!!!!
2838 // !!!!!!!! Obscure copy of the old Image !!!!!!!!!!!
2839 const MFUInt8 srcPixel = *getMFPixel();
2841 // set image data
2843 destImage->set(PixelFormat(getPixelFormat()),
2844 width,
2845 height,
2846 depth,
2847 getMipMapCount(),
2848 getFrameCount (),
2849 getFrameDelay (),
2851 getDataType (),
2852 true,
2853 getSideCount ());
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()) ;
2868 if(mipmap)
2870 src += calcMipmapSumSize (mipmap,
2871 oldWidth,
2872 oldHeight,
2873 oldDepth);
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);
2892 return true;
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,
2901 bool vertical,
2902 bool flipDepth,
2903 Image *destination)
2905 if ( !horizontal && !vertical)
2907 if(destination != NULL)
2908 *destination = *this;
2910 return true;
2913 Image *destImage;
2915 if(destination != NULL)
2917 destImage = destination;
2919 else
2921 destImage = this;
2924 // Get pixels.
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()),
2934 width,
2935 height,
2936 depth,
2937 getMipMapCount(),
2938 getFrameCount (),
2939 getFrameDelay (),
2941 getDataType (),
2942 true,
2943 getSideCount ());
2945 Int32 frame, side, mipmap;
2946 const UChar8 *src;
2947 UChar8 *dest;
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());
2961 if(mipmap)
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);
2975 return true;
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 ()),
2988 destination );
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,
2997 Int32 offY,
2998 Int32 offZ,
2999 Int32 destW,
3000 Int32 destH,
3001 Int32 destD,
3002 Image *destination)
3004 ImageUnrecPtr destImage(destination);
3005 bool retCode = true;
3007 if (hasCompressedData())
3009 FFATAL (("Invalid Image::subImage for compressed image\n"));
3010 return false;
3013 if(destination == NULL)
3015 destImage = Image::create();
3018 destImage->set(PixelFormat(getPixelFormat()),
3019 destW,
3020 destH,
3021 destD,
3024 0.0,
3026 getDataType());
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
3038 UInt32 xMin = offX;
3039 UInt32 yMin = offY;
3040 UInt32 zMin = offZ;
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
3047 UInt32 destIdx = 0;
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];
3059 destIdx++;
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);
3075 return retCode;
3078 /*! Crop a slice.
3079 The method can operate on the object or stores the result in
3080 the optional destination Image.
3083 bool Image::slice(Int32 offX,
3084 Int32 offY,
3085 Int32 offZ,
3086 Image *destination)
3088 ImageUnrecPtr destImage(destination);
3089 bool retCode = true;
3090 UInt32 counter = 0;
3092 if (hasCompressedData())
3094 FFATAL (("Invalid Image::slice for compressed image\n"));
3095 return false;
3098 if(destination == NULL)
3100 destImage = Image::create();
3103 FDEBUG(("Image::slice (%d %d %d)\n",
3104 offX, offY, offZ));
3106 if(offX >= 0)
3107 counter++;
3109 if(offY >= 0)
3110 counter++;
3112 if(offZ >= 0)
3113 counter++;
3115 if(counter != 1)
3117 FWARNING(("Image::slice - more/less than one non negative value\n"));
3118 return false;
3121 if(offZ >= 0)
3123 // XY slice
3124 retCode = subImage(0,
3126 offZ,
3127 getWidth (),
3128 getHeight(),
3130 destImage );
3133 if(offY >= 0)
3135 // XZ slice
3136 destImage->set(PixelFormat(getPixelFormat()),
3137 getWidth(),
3138 getDepth(),
3142 0.0,
3144 getDataType());
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) *
3160 getBpp() + i];
3166 if(offX >= 0)
3168 // YZ slice
3169 destImage->set(PixelFormat(getPixelFormat()),
3170 getWidth(),
3171 getDepth(),
3175 0.0,
3177 getDataType());
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) *
3193 getBpp() + i];
3199 // rip the data from the local destImage if necessary
3200 if(destination == NULL)
3202 this->set(destImage);
3205 return retCode;
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)
3215 struct Offset
3217 Int32 d;
3218 Int32 h;
3219 Int32 w;
3222 Offset offset[][8] =
3224 { // 000
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 }
3228 { // 100
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 }
3232 { // 010
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 }
3236 { // 110
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 }
3240 { // 001
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 }
3244 { // 101
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 }
3248 { // 011
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 }
3252 { // 111
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;
3265 const UChar8 *src;
3266 UChar8 *dest;
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"));
3279 return false;
3282 if(destImage == NULL)
3284 destImage = Image::create();
3287 Real32 valueFloat;
3288 Int32 value, i, elem, dim, side, frame, size, mipmap;
3289 Int32 channel, lineSize, sliceSize;
3291 // calc the level count
3292 if(level < 0)
3294 level = calcMipmapLevelCount();
3297 // create destination image
3298 destImage->set(getPixelFormat(),
3299 getWidth(),
3300 getHeight(),
3301 getDepth(),
3302 level,
3303 getFrameCount(),
3304 getFrameDelay(),
3306 getDataType(),
3307 true,
3308 getSideCount());
3310 // copy the data;
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);
3326 src = dest;
3328 dest = dest + size;
3330 w = getWidth ();
3331 h = getHeight();
3332 d = getDepth ();
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++)
3355 value = 0;
3357 for(i = 0; i < elem; i++)
3359 value += src[
3360 ((wi * 2) + offset[dim][i].w) * getBpp() +
3361 ((hi * 2) + offset[dim][i].h) * lineSize +
3362 ((di * 2) + offset[dim][i].d) * sliceSize +
3363 channel];
3366 *dest++ = Int8(value / elem);
3372 src += sliceSize;
3374 w = wm;
3375 h = hm;
3376 d = dm;
3380 break;
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);
3395 src = dest;
3396 dest = dest + size;
3398 w = getWidth ();
3399 h = getHeight();
3400 d = getDepth ();
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++)
3424 for(channel = 0;
3425 channel < (getBpp() / getComponentSize());
3426 channel++)
3428 value = 0;
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 +
3436 channel];
3439 *destDataUC16++ = UInt16(value / elem);
3445 sourceDataUC16 += sliceSize;
3447 w = wm;
3448 h = hm;
3449 d = dm;
3453 break;
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);
3468 src = dest;
3469 dest = dest + size;
3471 w = getWidth ();
3472 h = getHeight();
3473 d = getDepth ();
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++)
3497 for(channel = 0;
3498 channel < (getBpp()/getComponentSize());
3499 channel++)
3501 value = 0;
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 +
3509 channel]/elem);
3511 *destDataUC32++ = UInt32(value);
3517 sourceDataUC32 += sliceSize;
3519 w = wm;
3520 h = hm;
3521 d = dm;
3525 break;
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);
3540 src = dest;
3541 dest = dest + size;
3543 w = getWidth ();
3544 h = getHeight();
3545 d = getDepth ();
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++)
3569 for(channel = 0;
3570 channel < (getBpp() / getComponentSize());
3571 channel++)
3573 valueFloat = 0;
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 +
3581 channel];
3584 *destDataF32++ = Real32(valueFloat / elem);
3590 sourceDataF32 += sliceSize;
3592 w = wm;
3593 h = hm;
3594 d = dm;
3598 break;
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);
3609 src = dest;
3610 dest = dest + size;
3611 w = getWidth();
3612 h = getHeight();
3613 d = getDepth();
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++)
3637 valueFloat = 0;
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 +
3644 channel];
3646 *destDataH16++ = Real16(valueFloat / elem);
3651 sourceDataH16 += sliceSize;
3652 w = wm;
3653 h = hm;
3654 d = dm;
3658 break;
3660 case OSG_INT16_IMAGEDATA:
3661 case OSG_INT32_IMAGEDATA:
3663 FFATAL((" 'createMipmap' NYI\n "));
3665 break;
3667 default:
3668 FWARNING (( "Invalid IMAGE_DATA_TYPE\n" ));
3669 break;
3672 // rip the data from the local destImage if necessary
3673 if(destination == NULL)
3675 this->set(destImage);
3678 return true;
3681 bool Image::removeMipmap(void)
3683 if(getMipMapCount() == 1) // no mipmaps nothing to do.
3684 return true;
3686 // create destination image
3687 ImageUnrecPtr destImage = Image::create();
3689 destImage->set(getPixelFormat(),
3690 getWidth (),
3691 getHeight (),
3692 getDepth (),
3694 getFrameCount (),
3695 getFrameDelay (),
3696 NULL,
3697 getDataType (),
3698 true,
3699 getSideCount ());
3701 if(!destImage->isValid())
3703 destImage = NULL;
3705 return false;
3708 // copy the data;
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);
3725 destImage = NULL;
3727 return true;
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,
3757 mimeType,
3758 mem,
3759 memSize);
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) :
3779 Inherited (),
3780 _mipmapOffset(),
3781 _hash (0),
3782 _hashValid (false)
3786 /*! Copy Constructor. Creates a copy of the given image
3789 Image::Image(const Image &obj) :
3790 Inherited (obj ),
3791 _mipmapOffset(obj._mipmapOffset),
3792 _hash (obj._hash ),
3793 _hashValid (obj._hashValid )
3797 /*! Destructor.
3800 Image::~Image(void)
3804 /*! Method to check, whether the object data defines a alpha channel or not
3807 bool Image::hasAlphaChannel(void)
3809 return
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/
3827 fully opaque
3829 bool Image::isAlphaBinary(void)
3831 return
3832 (getForceAlphaBinary() == true ) ||
3833 (getPixelFormat () == OSG_RGBA_DXT1);
3836 /*! Method to check, whether the data is compressed
3838 bool Image::hasCompressedData(void)
3840 return
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)
3853 return
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)
3889 return true;
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"));
3895 return false;
3898 UInt32 npix = getWidth() * getHeight() * getDepth() * getFrameCount();
3899 UInt8 pixelsize = getBpp();
3901 const UInt8 *data = getData();
3903 switch(getPixelFormat())
3905 case OSG_LA_PF:
3906 data += getComponentSize(); break;
3907 case OSG_BGRA_PF:
3908 case OSG_RGBA_PF:
3909 data += getComponentSize() * 3; break;
3910 default:
3911 FWARNING(("Image::calcIsAlphaBinary: found unknown "
3912 "image format %x, assumning false.\n",
3913 getPixelFormat()));
3914 return false;
3917 switch(getDataType())
3919 case OSG_UINT8_IMAGEDATA:
3920 for(; npix > 0; --npix, data += pixelsize)
3922 if(*data != 0 && *data != 0xffU)
3923 break;
3925 break;
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)
3931 break;
3933 break;
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)
3939 break;
3941 break;
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)
3947 break;
3949 break;
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)
3955 break;
3957 break;
3958 case OSG_INT16_IMAGEDATA:
3959 case OSG_INT32_IMAGEDATA:
3961 FFATAL((" 'calcIsAlphaBinary' NYI\n "));
3963 break;
3965 default:
3966 FWARNING(("Image::calcIsAlphaBinary: found unknown "
3967 "data type %d, assumning false.\n",
3968 getDataType()));
3969 return false;
3972 return npix == 0;
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,
3988 UInt32 &width,
3989 UInt32 &height,
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 ;
3997 #ifdef __sgi
3998 #pragma set woff 1209
3999 #endif
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();
4006 UInt32 level;
4008 for (level = 1; true; level++)
4010 if ((w == 1) && (h == 1) && (d == 1))
4012 break;
4014 else
4016 w = (w >>= 1) ? w : 1;
4017 h = (h >>= 1) ? h : 1;
4018 d = (d >>= 1) ? d : 1;
4021 return level;
4024 #ifdef __sgi
4025 #pragma reset woff 1209
4026 #endif
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
4036 Int32 sum;
4038 switch (getPixelFormat())
4040 case OSG_RGB_DXT1:
4041 case OSG_RGBA_DXT1:
4042 sum = (((w?w:1)+3)/4) * (((h?h:1)+3)/4) * 8;
4043 break;
4044 case OSG_RGBA_DXT3:
4045 case OSG_RGBA_DXT5:
4046 sum = (((w?w:1)+3)/4) * (((h?h:1)+3)/4) * 16;
4047 break;
4048 default:
4049 sum = (w?w:1) * (h?h:1) * getBpp();
4050 break;
4053 sum *= (d?d:1);
4055 return sum;
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
4064 UInt32 w, h, d;
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,
4073 UInt32 w,
4074 UInt32 h,
4075 UInt32 d) const
4077 Int32 sum = 0;
4079 if (w && h && d)
4081 while (mipmapNum--)
4083 sum += calcMipmapLevelSize(mipmapNum,w,h,d);
4085 w >>= 1;
4086 h >>= 1;
4087 d >>= 1;
4091 return sum;
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 /*-------------------------------------------------------------------------*/
4103 /* Image data */
4105 /*! Internal method to set the data and update related properties.
4108 bool Image::createData(const UInt8 *data, bool allocMem)
4110 Int32 i;
4111 Int32 mapSizeFormat = sizeof(_formatDic) / sizeof(UInt32[2]);
4112 Int32 mapSizeType = sizeof(_typeDic ) / sizeof(UInt32[2]);
4114 UInt32 byteCount = 0;
4116 // set bpp
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];
4125 break;
4129 for(i = 0; i < mapSizeType; i++)
4131 if(_typeDic[i][0] == getDataType())
4133 typeFormat = _typeDic[i][1];
4134 break;
4138 setComponentSize(typeFormat );
4139 setBpp (pixelFormat * typeFormat);
4141 // set dimension
4142 setDimension(0);
4144 if(getDepth() == 1)
4146 if(getHeight() == 1)
4148 setDimension(1);
4150 else
4152 setDimension(2);
4155 else
4157 setDimension(3);
4160 // set sideSize
4161 UInt32 mipmapSumSize = calcMipmapSumSize(getMipMapCount());
4162 setSideSize (mipmapSumSize);
4164 // set frameSize
4165 setFrameSize(getSideSize() * getSideCount());
4168 // copy the data
4169 if(allocMem && (byteCount = getSize()))
4171 if(getMFPixel()->size() != byteCount)
4175 if(byteCount < getMFPixel()->size())
4177 editMFPixel()->clear();
4178 // free unused memory.
4179 MFUInt8 tmp;
4180 tmp.swap(*editMFPixel());
4182 editMFPixel()->resize(byteCount);
4184 catch(...)
4186 FFATAL(("Image::createData : Couldn't allocate %u bytes!\n",
4187 byteCount));
4189 return false;
4193 if(data)
4195 memcpy(editData(), data, byteCount);
4198 else
4200 editMFPixel()->clear();
4203 return (getData() != NULL);
4206 /*! Internal method to scale image data blocks
4208 bool Image::scaleData(const UInt8 *srcData,
4209 Int32 srcW,
4210 Int32 srcH,
4211 Int32 srcD,
4212 UInt8 *destData,
4213 Int32 destW,
4214 Int32 destH,
4215 Int32 destD )
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;
4225 Int32 x, y, z, p;
4226 const UInt8 *pSlice;
4227 const UInt8 *pLine;
4228 const UInt8 *pPixel;
4230 if(destW == srcW && destH == srcH && destD == srcD)
4232 // same size, just copy
4233 memcpy(destData, srcData, srcSize);
4235 else
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();
4249 p = getBpp();
4251 while(p--)
4253 *destData++ = *pPixel++;
4260 return true;
4263 void Image::calcMipmapOffsets(void)
4265 UInt32 mipMapCount = getMipMapCount();
4267 if(mipMapCount == 0)
4268 mipMapCount = 1;
4270 _mipmapOffset.resize(mipMapCount);
4273 for(UInt32 i=0;i<mipMapCount;++i)
4274 _mipmapOffset[i] = calcMipmapSumSize[i];
4277 Int32 sum = 0;
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;
4291 w >>= 1;
4292 h >>= 1;
4293 d >>= 1;
4297 void Image::calcHash(void) const
4299 _hash = 173;
4301 boost::hash_range(_hash, _mfPixel.begin(), _mfPixel.end());
4302 _hashValid = true;
4305 /*! Internal method to mirror image data blocks
4307 bool Image::mirrorData(const UInt8 *srcData,
4308 UInt8 *destData,
4309 Int32 width,
4310 Int32 height,
4311 Int32 depth,
4312 bool horizontal,
4313 bool vertical,
4314 bool flipDepth)
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;
4323 int dz = dz_start;
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);
4328 int dy = dy_start;
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);
4333 int dx = dx_start;
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());
4339 Int32 p = getBpp();
4341 while(p--)
4343 *dst_pixel++ = *src_pixel++;
4348 return true;
4351 /*! Assign operator. Does a copy of the given Image object.
4354 Image &Image::operator=(const Image &image)
4356 this->set(PixelFormat(image.getPixelFormat()),
4357 image.getWidth (),
4358 image.getHeight (),
4359 image.getDepth (),
4360 image.getMipMapCount(),
4361 image.getFrameCount (),
4362 image.getFrameDelay (),
4363 image.getData (),
4364 image.getDataType (),
4365 true,
4366 image.getSideCount ());
4368 return *this;
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])
4400 return false;
4402 return true;
4404 return false;
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);
4416 #if 0
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.
4427 void
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);
4444 #endif
4446 OSG_END_NAMESPACE