1 /*---------------------------------------------------------------------------*\
5 * Copyright (C) 2000-2002 by the OpenSG Forum *
7 * contact: dirk@opensg.org, gerrit.voss@vossg.org, jbehr@zgdv.de *
9 \*---------------------------------------------------------------------------*/
10 /*---------------------------------------------------------------------------*\
13 * This library is free software; you can redistribute it and/or modify it *
14 * under the terms of the GNU Library General Public License as published *
15 * by the Free Software Foundation, version 2. *
17 * This library is distributed in the hope that it will be useful, but *
18 * WITHOUT ANY WARRANTY; without even the implied warranty of *
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
20 * Library General Public License for more details. *
22 * You should have received a copy of the GNU Library General Public *
23 * License along with this library; if not, write to the Free Software *
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
26 \*---------------------------------------------------------------------------*/
27 /*---------------------------------------------------------------------------*\
35 \*---------------------------------------------------------------------------*/
36 //---------------------------------------------------------------------------
38 //---------------------------------------------------------------------------
40 #if __GNUC__ >= 4 || __GNUC_MINOR__ >=3
41 #pragma GCC diagnostic warning "-Wsign-compare"
45 #pragma warning( disable : 4018 )
51 #include "OSGConfig.h"
54 #include "OSGBaseFunctions.h"
56 #include "OSGImageFunctions.h"
60 #if defined(OSG_WIN32_ICL) && !defined(OSG_CHECK_FIELDSETARG)
61 #pragma warning(disable : 383)
67 /***************************************************************************\
69 \***************************************************************************/
71 //---------------------------------------------------------------------------//
72 /*! composes multiple images to one */
75 //---------------------------------------------------------------------------//
76 /*! convert bumpmap to normalmap */
78 bool createNormalMapFromBump ( Image
*image
,
82 if (image
== NULL
|| image
->getDepth() > 1 ||
83 image
->getPixelFormat() != Image::OSG_L_PF
)
85 FFATAL(("No valid Normalmap given!\n"));
95 dst
= Image::create();
103 Int32 w
= image
->getWidth();
104 Int32 h
= image
->getHeight();
106 const unsigned char *srcData
= image
->getData();
108 dst
->set(Image::OSG_RGB_PF
, w
, h
);
110 unsigned char *dstData
= dst
->editData();
112 Vec3f
scale(normalMapScale
);
114 if (scale
[0] == 0.0f
|| scale
[1] == 0.0f
|| scale
[2] == 0.0f
)
116 Real32 a
= Real32(w
) / Real32(h
);
133 for (i
=1; i
<w
-1; i
++)
135 for (j
=1; j
<h
-1; j
++)
137 Vec3f
dfdi(2.0f
, 0.0f
, Real32(srcData
[(i
+1) + j
*w
] - srcData
[(i
-1) + j
*w
]) / 255.0f
);
138 Vec3f
dfdj(0.0f
, 2.0f
, Real32(srcData
[ i
+ (j
+1)*w
] - srcData
[ i
+ (j
-1)*w
]) / 255.0f
);
139 Vec3f n
= dfdi
.cross(dfdj
);
146 dstData
[(j
*w
+i
)*3+0] = UInt8((n
[0]+1)*127.5);
147 dstData
[(j
*w
+i
)*3+1] = UInt8((n
[1]+1)*127.5);
148 dstData
[(j
*w
+i
)*3+2] = UInt8((n
[2]+1)*127.5);
152 // handle image border
155 dstData
[i
*3+0] = dstData
[(w
+i
)*3+0];
156 dstData
[i
*3+1] = dstData
[(w
+i
)*3+1];
157 dstData
[i
*3+2] = dstData
[(w
+i
)*3+2];
159 dstData
[((h
-1)*w
+i
)*3+0] = dstData
[((h
-2)*w
+1)*3+0];
160 dstData
[((h
-1)*w
+i
)*3+1] = dstData
[((h
-2)*w
+1)*3+1];
161 dstData
[((h
-1)*w
+i
)*3+2] = dstData
[((h
-2)*w
+1)*3+2];
166 dstData
[(j
*w
)*3+0] = dstData
[(j
*w
+1)*3+0];
167 dstData
[(j
*w
)*3+1] = dstData
[(j
*w
+1)*3+1];
168 dstData
[(j
*w
)*3+2] = dstData
[(j
*w
+1)*3+2];
170 dstData
[(j
*w
+(w
-1))*3+0] = dstData
[(j
*w
+(w
-2))*3+0];
171 dstData
[(j
*w
+(w
-1))*3+1] = dstData
[(j
*w
+(w
-2))*3+1];
172 dstData
[(j
*w
+(w
-1))*3+2] = dstData
[(j
*w
+(w
-2))*3+2];
186 //---------------------------------------------------------------------------//
187 /*! creates a Normal Volume from the given data */
189 bool createNormalVolume ( Image
*inImage
,
191 const std::string
&outputFormat
)
193 const Real32 gMax
= 441.67295593f
, gF
= 255.0f
/gMax
;
194 // const OSG::Real32 TwoPi = 2 * OSG::Pi;
196 enum DataIndex
{ SCALAR_DI
,
205 const UInt8
*data
= 0;
207 OSG::Real32 minU
= OSG::Inf
, maxU
= -OSG::Inf
;
208 OSG::Real32 minV
= OSG::Inf
, maxV
= -OSG::Inf
;
209 Int32 w
, h
, d
, x
, y
, z
, md
, ld
, hd
, xs
, ys
, zs
, ps
, ls
, ss
, os
;
211 std::vector
<UInt32
> dataIndex
;
215 Image::PixelFormat pf
;
216 bool calcGradient
= false, calcThetaPhi
= false;
217 char validFormat
[END_DI
];
218 UInt8 voxelData
[sizeof(validFormat
)];
222 // init valid format string
223 validFormat
[SCALAR_DI
] = 's';
224 validFormat
[SCALAR_NULLEDGE_DI
] = 'S';
225 validFormat
[X_DI
] = 'x';
226 validFormat
[Y_DI
] = 'y';
227 validFormat
[Z_DI
] = 'z';
228 validFormat
[GRADIENT_DI
] = 'g';
229 validFormat
[THETA_DI
] = 't';
230 validFormat
[PHI_DI
] = 'p';
232 if(inImage
== NULL
|| outImage
== NULL
)
237 // check if we have a valid input image
238 if ( inImage
->getBpp() != 1 ) {
240 copy
= Image::create();
241 FLOG (("Create copy to reformat/convert Image\n"));
243 if ( (inImage
->getPixelFormat() == Image::OSG_L_PF
) ||
244 (inImage
->getPixelFormat() == Image::OSG_L_PF
) )
247 inImage
->reformat(Image::OSG_L_PF
,copy
);
250 if (inImage
->getDataType() != Image::OSG_UINT8_IMAGEDATA
)
251 inImage
->convertDataTypeTo(Image::OSG_UINT8_IMAGEDATA
);
254 switch (outputFormat
.size()) {
256 pf
= Image::OSG_L_PF
;
259 pf
= Image::OSG_LA_PF
;
262 pf
= Image::OSG_RGB_PF
;
265 pf
= Image::OSG_RGBA_PF
;
268 FFATAL(( "Invalid outputFormat length in createNormalVolume: %"
270 outputFormat
.size() ));
274 // get image data and parameter
275 w
= inImage
->getWidth();
276 h
= inImage
->getHeight();
277 d
= inImage
->getDepth();
278 data
= inImage
->getData();
279 ps
= inImage
->getBpp();
284 // check format string and fill dataIndex
285 voxelSize
= outputFormat
.size();
286 dataIndex
.resize(voxelSize
);
287 for (i
= 0; i
< voxelSize
; i
++) {
288 if ((formatP
= strchr(validFormat
, outputFormat
[i
]))) {
289 dataIndex
[i
] = (formatP
- validFormat
);
290 switch (dataIndex
[i
]) {
299 FDEBUG (( "dataIndex[%" PRISize
"]: %d\n", i
, dataIndex
[i
] ));
302 FFATAL (( "Invalid outputFormat element %c, valid: %s\n",
303 char(outputFormat
[i
]), validFormat
));
308 // create output image
309 outImage
->set( pf
, w
, h
, d
);
311 ds
= outImage
->editData();
314 for (z
= 0; z
< d
; z
++) {
315 for (y
= 0; y
< h
; y
++) {
316 for (x
= 0; x
< w
; x
++) {
319 md
= data
[(x
*ps
) + (y
*ls
) + (z
*ss
) + os
];
323 ld
= data
[((x
-1)*ps
) + (y
*ls
) + (z
*ss
) + os
];
329 hd
= data
[((x
+1)*ps
) + (y
*ls
) + (z
*ss
) + os
];
338 ld
= data
[(x
*ps
) + ((y
-1)*ls
) + (z
*ss
) + os
];
344 hd
= data
[(x
*ps
) + ((y
+1)*ls
) + (z
*ss
) + os
];
353 ld
= data
[(x
*ps
) + (y
*ls
) + ((z
-1)*ss
) + os
];
359 hd
= data
[(x
*ps
) + (y
*ls
) + ((z
+1)*ss
) + os
];
366 // set the voxel data
367 voxelData
[SCALAR_DI
] = md
;
368 voxelData
[SCALAR_NULLEDGE_DI
] = isEdge
? 0 : md
;
369 voxelData
[X_DI
] = xs
/ 2 + 127;
370 voxelData
[Y_DI
] = ys
/ 2 + 127;
371 voxelData
[Z_DI
] = zs
/ 2 + 127;
374 if (calcGradient
|| calcThetaPhi
) {
375 normal
.setValues (xs
,ys
,zs
);
376 length
= normal
.length();
382 voxelData
[GRADIENT_DI
] = osgMax ( int (length
* gF
), 255 );
387 v
= OSG::osgACos(normal
[2]) / OSG::Pi
;
388 u
= OSG::osgSqrt(normal
[0]*normal
[0] + normal
[1]*normal
[1]);
390 if (u
) u
= normal
[0] / u
;
392 if (normal
[1]<0) u
= TwoPi
- u
;
400 voxelData
[THETA_DI
] = UInt8(v
* 255.f
); // theta
401 voxelData
[PHI_DI
] = UInt8(u
* 255.f
); // phi
404 // copy voxeldata to image data
405 for (i
= 0; i
< voxelSize
; i
++)
406 *ds
++ = voxelData
[dataIndex
[i
]];
416 //---------------------------------------------------------------------------//
417 /*! create pre-integrated lookup table
418 code based on the "Truly Volumetric Effects" (Martin Kraus)
419 example in the ShaderX book (www.shaderx.com)
422 bool create2DPreIntegrationLUT ( Image
*dst
,
426 if (src
== NULL
|| dst
== NULL
||
427 src
->getHeight() > 1 || src
->getDepth() > 1 ||
428 src
->getPixelFormat() != Image::OSG_RGBA_PF
)
430 FFATAL(("No appropriate image given!\n"));
434 const unsigned char *dataSrc
= src
->getData();
435 UInt32 width
= src
->getWidth();
437 dst
->set(Image::OSG_RGBA_PF
, width
, width
);
439 unsigned char *dataDst
= dst
->editData();
441 for (Int32 x
= 0; x
< Int32(width
); x
++)
443 for (Int32 y
= 0; y
< Int32(width
); y
++)
445 Int32 n
= 10 + 2 * abs(x
-y
);
446 Real64 step
= thickness
/ n
;
453 for (Int32 i
= 0; i
< n
; i
++)
455 Real64 w
= x
+ (y
-x
) * Real64(i
)/n
;
457 if (Int32(w
+ 1) >= Int32(width
))
458 w
= Real64(width
- 1) - 0.5/n
;
460 Int32 pos
= (Int32(w
)) * 4;
462 Real64 e
= exp(-dtau
), scale
= step
* (1.0 / 255.0),
463 f
= w
- floor(w
), invF
= 1 - f
;
465 Real64 tau
= scale
* (dataSrc
[pos
+ 3] * f
+ dataSrc
[pos
+4 + 3] * invF
);
466 Real64 r
= e
* scale
* (dataSrc
[pos
+ 0] * f
+ dataSrc
[pos
+4 + 0] * invF
);
467 Real64 g
= e
* scale
* (dataSrc
[pos
+ 1] * f
+ dataSrc
[pos
+4 + 1] * invF
);
468 Real64 b
= e
* scale
* (dataSrc
[pos
+ 2] * f
+ dataSrc
[pos
+4 + 2] * invF
);
476 dataDst
[(x
*width
+y
)*4+0] = UInt8((dr
> 1.0 ? 1.0 : dr
)*255);
477 dataDst
[(x
*width
+y
)*4+1] = UInt8((dg
> 1.0 ? 1.0 : dg
)*255);
478 dataDst
[(x
*width
+y
)*4+2] = UInt8((db
> 1.0 ? 1.0 : db
)*255);
479 dataDst
[(x
*width
+y
)*4+3] = UInt8((1.0 - exp(-dtau
))*255);
489 //---------------------------------------------------------------------------//
490 /*! split RGBA images into RGB and A */
492 bool splitRGBA(Image
*rgba
,
496 if (rgba
== NULL
|| rgba
->getDepth() > 1 ||
497 rgba
->getPixelFormat() != Image::OSG_RGBA_PF
)
499 FFATAL(("No appropriate image given!\n"));
503 if(rgb
== NULL
|| alpha
== NULL
)
505 FFATAL(("No appropriate target given!\n"));
509 Int32 w
= rgba
->getWidth();
510 Int32 h
= rgba
->getHeight();
512 rgb
->set(Image::OSG_RGB_PF
, w
, h
);
513 alpha
->set(Image::OSG_L_PF
, w
, h
);
515 unsigned char *data
= rgb
->editData();
516 const unsigned char *dataRgba
= rgba
->getData();
517 unsigned char *dataAlpha
= alpha
->editData();
519 for (Int32 i
=0; i
<(w
* h
); i
++)
521 data
[0] = dataRgba
[0];
522 data
[1] = dataRgba
[1];
523 data
[2] = dataRgba
[2];
524 dataAlpha
[0] = dataRgba
[3];
537 //---------------------------------------------------------------------------//
538 /*! merge RGB and A images into RGBA */
540 bool mergeRGBA(Image
*rgb
,
544 if (rgb
== NULL
|| alpha
== NULL
||
545 rgb
->getDepth() > 1 || alpha
->getDepth() > 1 ||
546 rgb
->getPixelFormat() != Image::OSG_RGB_PF
||
547 alpha
->getPixelFormat() != Image::OSG_L_PF
)
549 FFATAL(("No appropriate images given!\n"));
555 FFATAL(("No appropriate target given!\n"));
560 Int32 w
= rgb
->getWidth();
561 Int32 h
= rgb
->getHeight();
563 if (w
!= alpha
->getWidth() || h
!= alpha
->getHeight())
565 FFATAL(("Colour and Alpha Images must be of same size!\n"));
569 rgba
->set(Image::OSG_RGBA_PF
, w
, h
);
571 unsigned char *data
= rgba
->editData();
572 const unsigned char *dataRgb
= rgb
->getData();
573 const unsigned char *dataAlpha
= alpha
->getData();
575 for (Int32 i
=0; i
<(w
* h
); i
++)
577 data
[0] = dataRgb
[0];
578 data
[1] = dataRgb
[1];
579 data
[2] = dataRgb
[2];
580 data
[3] = *dataAlpha
;
591 //---------------------------------------------------------------------------//
592 /*! blend the brush on the canvas image */
594 bool blendImage ( Image
*canvas
,
602 int red
= 0, green
= 0, blue
= 0, grey
= 0;
607 if(canvas
== NULL
|| brush
== NULL
)
609 FFATAL(("No appropriate images given!\n"));
613 const OSG::UChar8
*src
= brush
->getData();
614 OSG::UChar8
*dest
= canvas
->editData();
616 const float cred
= color
.red();
617 const float cgreen
= color
.green();
618 const float cblue
= color
.blue();
619 const float calpha
= color
.alpha();
620 const float talpha
= alphaScale
;
622 const int cPF
= canvas
->getPixelFormat();
623 const int bPF
= brush
->getPixelFormat();
625 const int cBpp
= canvas
->getBpp();
626 const int bBpp
= brush
->getBpp();
628 const int bW
= brush
->getWidth();
629 const int bH
= brush
->getHeight();
630 const int bD
= brush
->getDepth();
632 const int cW
= canvas
->getWidth();
633 const int cH
= canvas
->getHeight();
634 const int cD
= canvas
->getDepth();
636 const int xcOff
= int(position
.x());
637 const int ycOff
= int(position
.y());
638 const int zcOff
= int(position
.z());
640 // canvas->setSubData (xcOff,ycOff,zcOff,bW,bH,bD,src);
642 const int xcMin
= OSG::osgMax(0, xcOff
);
643 const int ycMin
= OSG::osgMax(0, ycOff
);
644 const int zcMin
= OSG::osgMax(0, zcOff
);
646 const int xcMax
= OSG::osgMin(cW
, xcOff
+ bW
);
647 const int ycMax
= OSG::osgMin(cH
, ycOff
+ bH
);
648 const int zcMax
= OSG::osgMin(cD
, zcOff
+ bD
);
650 const int width
= (xcMax
- xcMin
);
651 const int height
= (ycMax
- ycMin
);
652 const int depth
= (zcMax
- zcMin
);
654 int xbMin
= xcOff
< 0 ? -xcOff
: 0;
655 int ybMin
= ycOff
< 0 ? -ycOff
: 0;
656 int zbMin
= zcOff
< 0 ? -zcOff
: 0;
658 //select slice for volume brush
659 if ((bD
> 1) && (depth
== 1)) {
660 z
= int(OSG::osgAbs(paintZ
) * (bD
- 1)) % bD
;
661 src
+= bW
* bH
* bBpp
* z
;
665 for (z
= 0; z
< depth
; z
++) {
666 for (y
= 0; y
< height
; y
++){
667 d
= dest
+ ( ((z
+zcMin
) * cH
+ (y
+ycMin
)) * cW
+ xcMin
) * cBpp
;
668 s
= src
+ ( ((z
+zbMin
) * bH
+ (y
+ybMin
)) * bW
+ xbMin
) * bBpp
;
669 for (x
= 0; x
< width
; x
++) {
671 case OSG::Image::OSG_A_PF
:
672 case OSG::Image::OSG_I_PF
:
674 red
= int(cred
* grey
);
675 green
= int(cgreen
* grey
);
676 blue
= int(cblue
* grey
);
677 alpha
= int(calpha
* grey
);
679 case OSG::Image::OSG_L_PF
:
681 red
= int(cred
* grey
);
682 green
= int(cgreen
* grey
);
683 blue
= int(cblue
* grey
);
684 alpha
= int(calpha
* 255);
686 case OSG::Image::OSG_LA_PF
:
688 red
= int(cred
* grey
);
689 green
= int(cgreen
* grey
);
690 blue
= int(cblue
* grey
);
691 alpha
= int(calpha
* *s
++);
693 case OSG::Image::OSG_RGB_PF
:
694 red
= int(cred
* *s
++);
695 green
= int(cgreen
* *s
++);
696 blue
= int(cblue
* *s
++);
697 grey
= green
; // FIXME
700 case OSG::Image::OSG_RGBA_PF
:
701 red
= int(cred
* *s
++);
702 green
= int(cgreen
* *s
++);
703 blue
= int(cblue
* *s
++);
704 grey
= green
; // FIXME
705 alpha
= int(calpha
* *s
++);
708 FFATAL (("Invalid Brush PixelFormat\n"));
712 alpha
= int(talpha
* alpha
);
714 case OSG::Image::OSG_I_PF
:
715 *d
= int(*d
* (alpha
- 255) + grey
* alpha
) / 255;
718 case OSG::Image::OSG_L_PF
:
719 *d
= int(*d
* (alpha
- 255) + grey
* alpha
) / 255;
722 case OSG::Image::OSG_LA_PF
:
723 *d
= int(*d
* (alpha
- 255) + grey
* alpha
) / 255;
727 case OSG::Image::OSG_RGB_PF
:
728 *d
= int(*d
* (255 - alpha
) + red
* alpha
) / 255;
730 *d
= int(*d
* (255 - alpha
) + green
* alpha
) / 255;
732 *d
= int(*d
* (255 - alpha
) + blue
* alpha
) / 255;
735 case OSG::Image::OSG_RGBA_PF
:
736 *d
= int(*d
* (255 - alpha
) + red
* alpha
) / 255;
738 *d
= int(*d
* (255 - alpha
) + green
* alpha
) / 255;
740 *d
= int(*d
* (255 - alpha
) + blue
* alpha
) / 255;
745 FFATAL (("Invalid Canvas PixelFormat\n"));
756 //---------------------------------------------------------------------------//
757 /*! create phong texture */
759 bool createPhongTexture(Image
*image
,
761 Real32 specular_exponent
,
768 FFATAL(("No appropriate target given!\n"));
772 image
->set(Image::OSG_L_PF
, size
, size
);
773 unsigned char *textureMap
= image
->editData();
775 UInt32 i
, j
, index
= 0;
778 Real32 specular_factor
, diffuse_factor
;
779 Real32 textureRadius
= 0.95f
;
780 Real32 textureStep
= (2.0 * textureRadius
) / Real32(size
-1);
783 for (j
=0; j
<size
; j
++)
786 for (i
=0; i
<size
; i
++)
788 diffuse_factor
= sqrt(1.0 - x
* x
);
789 specular_factor
= pow( diffuse_factor
* sqrt (1.0f
- y
* y
) - x
* y
,
791 textureMap
[index
++] = UInt8((ka
+ kd
* diffuse_factor
+ ks
* specular_factor
) * 255);
802 //---------------------------------------------------------------------------//
803 /*! create phong Volume */
805 bool createPhongVolume ( Image
*image
,
806 Color3f diffuseColor
,
807 Color3f specularColor
,
812 const OSG::Int32 lutFSize
= lutSize
/ lutScalar
;
813 OSG::Real32 theta1
, theta2
, dPhi
, incr
= lutScalar
* lutIncr
;
814 OSG::Real32 Const
= 0.2f
, Shi
= 40, NdotL
;
816 OSG::Vec3f
diffuse (diffuseColor
[0],diffuseColor
[1],diffuseColor
[2]);
817 OSG::Vec3f
specular (specularColor
[0],specularColor
[1],specularColor
[2]);
819 OSG::Real32 min
= OSG::Inf
, max
= -OSG::Inf
;
823 FFATAL(("No appropriate target given!\n"));
827 image
->set( OSG::Image::OSG_RGB_PF
, lutFSize
, lutFSize
, lutFSize
);
829 ds
= image
->editData();
831 FDEBUG (("calc phong map START\n"));
833 for (dPhi
=0; dPhi
<360; dPhi
+=incr
) {
834 for (theta1
=0; theta1
<180; theta1
+=incr
) {
835 for (theta2
=0; theta2
<180; theta2
+=incr
) {
836 OSG::Real32 t1
= OSG::osgDegree2Rad(theta1
),
837 t2
= OSG::osgDegree2Rad(theta2
),
838 dp
= OSG::osgDegree2Rad(dPhi
);
839 NdotL
= OSG::osgSin(t1
)*OSG::osgSin(t2
)*OSG::osgCos(dp
) +
840 OSG::osgCos(t1
)*OSG::osgCos(t2
);
841 NdotL
= (NdotL
>= 0) ? NdotL
: 0;
842 color
= diffuse
* (NdotL
+ Const
) +
843 specular
* OSG::osgPow(NdotL
, Shi
);
845 for (int i
=0; i
<3; i
++) {
846 if (min
>color
[i
]) min
=color
[i
];
847 if (max
<color
[i
]) max
=color
[i
];
849 color
[i
] = OSG::osgClamp(0.f
, (color
[i
]), 1.f
);
850 *ds
++ = UInt8(color
[i
]*255);
857 FDEBUG (( "calc phong map FINISH: clamped from [%f,%f] to [0,1]\n",
864 //---------------------------------------------------------------------------//
865 /*! create normalization cube map */
867 bool createNormalizationCubeMap(std::vector
<Image
*> imageVec
,
872 if (imageVec
.size() < 6)
874 FFATAL(("Only %" PRISize
" images given - need six\n",
881 if (imageVec
[i
] == NULL
)
883 FFATAL(("Image[%d] is Null\n", i
));
888 unsigned char *data
= NULL
;
891 size
= osgNextPower2(size
);
893 float size2
= size
/ 2.0f
;
896 Image
*imagePosX
= imageVec
[0];
899 imagePosX
->set(Image::OSG_RGB_PF
, size
, size
);
900 data
= imagePosX
->editData();
902 for (j
=0; j
<size
; j
++) {
903 for (i
=0; i
<size
; i
++) {
906 n
[1] = -(Real32(j
) + offset
- size2
);
907 n
[2] = -(Real32(i
) + offset
- size2
);
910 data
[0] = UInt8(((n
.x() + 1.f
) / 2.f
) * 255.f
);
911 data
[1] = UInt8(((n
.y() + 1.f
) / 2.f
) * 255.f
);
912 data
[2] = UInt8(((n
.z() + 1.f
) / 2.f
) * 255.f
);
917 Image
*imageNegX
= imageVec
[1];
920 imageNegX
->set(Image::OSG_RGB_PF
, size
, size
);
921 data
= imageNegX
->editData();
923 for (j
=0; j
<size
; j
++) {
924 for (i
=0; i
<size
; i
++) {
927 n
[1] = -(Real32(j
) + offset
- size2
);
928 n
[2] = (Real32(i
) + offset
- size2
);
931 data
[0]= UInt8(((n
.x() + 1.f
) / 2.f
) * 255.f
);
932 data
[1]= UInt8(((n
.y() + 1.f
) / 2.f
) * 255.f
);
933 data
[2]= UInt8(((n
.z() + 1.f
) / 2.f
) * 255.f
);
938 Image
*imagePosY
= imageVec
[2];
941 imagePosY
->set(Image::OSG_RGB_PF
, size
, size
);
942 data
= imagePosY
->editData();
944 for (j
=0; j
<size
; j
++) {
945 for (i
=0; i
<size
; i
++) {
947 n
[0] = (Real32(i
) + offset
- size2
);
949 n
[2] = (Real32(j
) + offset
- size2
);
952 data
[0]= UInt8(((n
.x() + 1.f
) / 2.f
) * 255.f
);
953 data
[1]= UInt8(((n
.y() + 1.f
) / 2.f
) * 255.f
);
954 data
[2]= UInt8(((n
.z() + 1.f
) / 2.f
) * 255.f
);
959 Image
*imageNegY
= imageVec
[3];
962 imageNegY
->set(Image::OSG_RGB_PF
, size
, size
);
963 data
= imageNegY
->editData();
965 for (j
=0; j
<size
; j
++) {
966 for (i
=0; i
<size
; i
++) {
968 n
[0]= (Real32(i
) + offset
- size2
);
970 n
[2]= -(Real32(j
) + offset
- size2
);
973 data
[0] = UInt8(((n
.x() + 1.f
) / 2.f
) * 255.f
);
974 data
[1] = UInt8(((n
.y() + 1.f
) / 2.f
) * 255.f
);
975 data
[2] = UInt8(((n
.z() + 1.f
) / 2.f
) * 255.f
);
980 Image
*imagePosZ
= imageVec
[4];
983 imagePosZ
->set(Image::OSG_RGB_PF
, size
, size
);
984 data
= imagePosZ
->editData();
986 for (j
=0; j
<size
; j
++) {
987 for (i
=0; i
<size
; i
++) {
989 n
[0] = (Real32(i
) + offset
- size2
);
990 n
[1] = -(Real32(j
) + offset
- size2
);
994 data
[0] = UInt8(((n
.x() + 1.f
) / 2.f
) * 255.f
);
995 data
[1] = UInt8(((n
.y() + 1.f
) / 2.f
) * 255.f
);
996 data
[2] = UInt8(((n
.z() + 1.f
) / 2.f
) * 255.f
);
1001 Image
*imageNegZ
= imageVec
[5];
1004 imageNegZ
->set(Image::OSG_RGB_PF
, size
, size
);
1005 data
= imageNegZ
->editData();
1007 for (j
=0; j
<size
; j
++) {
1008 for (i
=0; i
<size
; i
++) {
1010 n
[0] = -(Real32(i
) + offset
- size2
);
1011 n
[1] = -(Real32(j
) + offset
- size2
);
1015 data
[0] = UInt8(((n
.x() + 1.f
) / 2.f
) * 255.f
);
1016 data
[1] = UInt8(((n
.y() + 1.f
) / 2.f
) * 255.f
);
1017 data
[2] = UInt8(((n
.z() + 1.f
) / 2.f
) * 255.f
);
1026 //---------------------------------------------------------------------------//
1027 /*! Noise code; first some helpers */
1029 /************************************************************************
1031 * Copyright (C) 2002-2004 3Dlabs Inc. Ltd. *
1033 * All rights reserved. *
1035 * Redistribution and use in source and binary forms, with or without *
1036 * modification, are permitted provided that the following conditions *
1039 * Redistributions of source code must retain the above copyright *
1040 * notice, this list of conditions and the following disclaimer. *
1042 * Redistributions in binary form must reproduce the above *
1043 * copyright notice, this list of conditions and the following *
1044 * disclaimer in the documentation and/or other materials provided *
1045 * with the distribution. *
1047 * Neither the name of 3Dlabs Inc. Ltd. nor the names of its *
1048 * contributors may be used to endorse or promote products derived *
1049 * from this software without specific prior written permission. *
1051 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
1052 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT *
1053 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS *
1054 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE *
1055 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, *
1056 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, *
1057 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; *
1058 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER *
1059 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT *
1060 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN *
1061 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
1062 * POSSIBILITY OF SUCH DAMAGE. *
1064 ************************************************************************/
1072 Int32 p
[MAXB
+ MAXB
+ 2];
1073 Real32 g3
[MAXB
+ MAXB
+ 2][3];
1074 Real32 g2
[MAXB
+ MAXB
+ 2][2];
1075 Real32 g1
[MAXB
+ MAXB
+ 2];
1081 void setNoiseFrequency(Int32 frequency
)
1088 Real32
lerp(Real32 t
, Real32 a
, Real32 b
)
1090 return (1 - t
) * a
+ t
* b
;
1093 Real32
sCurve(Real32 t
)
1095 return t
* t
* (3.0f
- 2.0f
* t
);
1098 Real32
at2(Real32
*q
, Real32 rx
, Real32 ry
)
1100 return rx
* q
[0] + ry
* q
[1];
1103 Real32
at3(Real32
*q
, Real32 rx
, Real32 ry
, Real32 rz
)
1105 return rx
* q
[0] + ry
* q
[1] + rz
* q
[2];
1108 void setup(Real32
*vec
, UInt8 i
,
1110 Int32
&b0
, Int32
&b1
,
1111 Real32
&r0
, Real32
&r1
)
1113 t
= vec
[i
] + 0x1000;
1114 b0
= (Int32(t
)) & BM
;
1120 void normalize2(Real32 v
[2])
1122 Real32 s
= sqrt(v
[0] * v
[0] + v
[1] * v
[1]);
1127 void normalize3(Real32 v
[3])
1129 Real32 s
= sqrt(v
[0] * v
[0] + v
[1] * v
[1] + v
[2] * v
[2]);
1140 for (i
= 0 ; i
< B
; i
++)
1143 g1
[i
] = Real32((rand() % (B
+ B
)) - B
) / B
;
1145 for (j
= 0 ; j
< 2 ; j
++)
1146 g2
[i
][j
] = Real32((rand() % (B
+ B
)) - B
) / B
;
1149 for (j
= 0 ; j
< 3 ; j
++)
1150 g3
[i
][j
] = Real32((rand() % (B
+ B
)) - B
) / B
;
1157 p
[i
] = p
[j
= rand() % B
];
1161 for (i
= 0 ; i
< B
+ 2 ; i
++)
1165 for (j
= 0 ; j
< 2 ; j
++)
1166 g2
[B
+ i
][j
] = g2
[i
][j
];
1167 for (j
= 0 ; j
< 3 ; j
++)
1168 g3
[B
+ i
][j
] = g3
[i
][j
];
1172 Real32
noise1(Real32 vec
[1])
1175 Real32 rx0
, rx1
, sx
, t
, u
, v
;
1183 setup(vec
, 0, t
, bx0
, bx1
, rx0
, rx1
);
1187 u
= rx0
* g1
[ p
[ bx0
] ];
1188 v
= rx1
* g1
[ p
[ bx1
] ];
1190 return lerp(sx
, u
, v
);
1193 Real32
noise2(Real32 vec
[2])
1195 Int32 bx0
, bx1
, by0
, by1
, b00
, b10
, b01
, b11
;
1196 Real32 rx0
, rx1
, ry0
, ry1
, *q
, sx
, sy
, a
, b
, t
, u
, v
;
1205 setup(vec
, 0, t
, bx0
, bx1
, rx0
, rx1
);
1206 setup(vec
, 1, t
, by0
, by1
, ry0
, ry1
);
1219 q
= g2
[ b00
] ; u
= at2(q
, rx0
,ry0
);
1220 q
= g2
[ b10
] ; v
= at2(q
, rx1
,ry0
);
1223 q
= g2
[ b01
] ; u
= at2(q
, rx0
,ry1
);
1224 q
= g2
[ b11
] ; v
= at2(q
, rx1
,ry1
);
1227 return lerp(sy
, a
, b
);
1230 Real32
noise3(Real32 vec
[3])
1232 Int32 bx0
, bx1
, by0
, by1
, bz0
, bz1
, b00
, b10
, b01
, b11
;
1233 Real32 rx0
, rx1
, ry0
, ry1
, rz0
, rz1
, *q
, sy
, sz
, a
, b
, c
, d
, t
, u
, v
;
1242 setup(vec
, 0, t
, bx0
, bx1
, rx0
, rx1
);
1243 setup(vec
, 1, t
, by0
, by1
, ry0
, ry1
);
1244 setup(vec
, 2, t
, bz0
, bz1
, rz0
, rz1
);
1258 q
= g3
[ b00
+ bz0
] ; u
= at3(q
, rx0
,ry0
,rz0
);
1259 q
= g3
[ b10
+ bz0
] ; v
= at3(q
, rx1
,ry0
,rz0
);
1262 q
= g3
[ b01
+ bz0
] ; u
= at3(q
, rx0
,ry1
,rz0
);
1263 q
= g3
[ b11
+ bz0
] ; v
= at3(q
, rx1
,ry1
,rz0
);
1268 q
= g3
[ b00
+ bz1
] ; u
= at3(q
, rx0
,ry0
,rz1
);
1269 q
= g3
[ b10
+ bz1
] ; v
= at3(q
, rx1
,ry0
,rz1
);
1272 q
= g3
[ b01
+ bz1
] ; u
= at3(q
, rx0
,ry1
,rz1
);
1273 q
= g3
[ b11
+ bz1
] ; v
= at3(q
, rx1
,ry1
,rz1
);
1278 return lerp(sz
, c
, d
);
1281 Real32
noise(Real32 vec
[], Int32 len
)
1283 // noise functions over 1, 2, and 3 dimensions
1286 case 1: return noise1(vec
);
1287 case 2: return noise2(vec
);
1288 case 3: return noise3(vec
);
1290 default: return 0.0f
;
1297 /*! create a noise texture.
1301 bool createNoise(Image
*image
,
1302 Image::PixelFormat pixelformat
,
1308 Int32 f
, i
, j
, k
, c
, w
, h
, frequency
= 4;
1309 Real32 ni
[3], amp
= 0.5, inci
, incj
, inck
;
1310 unsigned char *data
, *ptr
= NULL
;
1315 FFATAL (("No output image given\n"));
1322 ok
= image
->set(pixelformat
, size
);
1326 ok
= image
->set(pixelformat
, size
, size
);
1331 ok
= image
->set(pixelformat
, size
, size
, size
);
1335 ok
= image
->set(pixelformat
, size
, size
);
1339 FWARNING(("createNoise: Use [1|2|3] for image dimension (default 2)\n"));
1343 if ( ! (ok
&& (data
= image
->editData())) )
1345 FFATAL(("createNoise: Could not create image\n"));
1349 UInt16 ncomp
= image
->getComponents();
1351 if(splitOctaves
&& numOctaves
> ncomp
)
1353 FWARNING(("createNoise: try to split %d octaves, but only have %d"
1354 " components!\n", numOctaves
, ncomp
));
1358 for (f
=0; f
<numOctaves
; ++f
, frequency
*=2, amp
*=0.5)
1362 setNoiseFrequency(frequency
);
1363 ni
[0] = ni
[1] = ni
[2] = 0;
1364 inci
= 1.0 / (size
/ Real32(frequency
));
1365 incj
= 1.0 / (size
/ Real32(frequency
));
1366 inck
= 1.0 / (size
/ Real32(frequency
));
1368 for (i
=0; i
<size
; ++i
, ni
[0]+=inci
)
1370 for (j
=0; j
<w
; ++j
, ni
[1]+=incj
)
1372 for (k
=0; k
<h
; ++k
, ni
[2]+=inck
)
1374 // calculate numOctaves of noise and scale to range [0;1]
1377 *(ptr
+f
) = UInt8(((noise(ni
, dim
) + 1) * amp
) * 128.0);
1383 for(c
= 0; c
< ncomp
; ++c
, ++ptr
, ni
[0] += 1)
1384 (*ptr
) += UInt8(((noise(ni
, dim
) + 1) * amp
) * 128.0);
1391 FNOTICE(("Generated %dD noise: octave %d/%d...\n", dim
, f
+1, numOctaves
));
1398 bool createGamma(Image
*pImg
, UInt32 size
, Real32 gamma
)
1402 FFATAL (("No output image given\n"));
1406 pImg
->set(Image::OSG_L_PF
,
1414 Image::OSG_FLOAT32_IMAGEDATA
);
1416 Real32
*pDst
= reinterpret_cast<Real32
*>(pImg
->editData());
1418 for(UInt32 i
= 0; i
< size
; i
++)
1420 Real32 x
= Real32(i
) / Real32(size
);
1422 pDst
[i
] = pow(x
, gamma
);
1428 bool createVignette(Image
*pImg
,
1436 FFATAL (("No output image given\n"));
1440 pImg
->set(Image::OSG_L_PF
,
1448 Image::OSG_FLOAT32_IMAGEDATA
);
1450 Real32
*pDst
= reinterpret_cast<Real32
*>(pImg
->editData());
1452 for(UInt32 y
= 0; y
< height
; y
++)
1454 for(UInt32 x
= 0; x
< width
; x
++)
1457 osgSqrt((x
- width
/ 2) * (x
- width
/ 2) +
1458 (y
- height
/ 2) * (y
- height
/ 2));
1464 Real32 t
= 1.0 - (radius
- r0
) / (r1
- r0
);
1465 Real32 a
= t
* 2 - 1;
1469 0.5 * a
* osgSqrt(1 - a
* a
)) / (0.5 * Pi
);
1471 pDst
[y
* width
+ x
] = reduce
;
1475 pDst
[y
* width
+ x
] = 0.0;
1480 pDst
[y
* width
+ x
] = 1.0;
1488 bool convertCrossToCubeMap(Image
const *pIn
,
1491 if(pIn
== NULL
|| pOut
== NULL
)
1493 FFATAL (("No appropriate images given\n"));
1497 OSG::UInt32 face_width
= pIn
->getWidth() / 3;
1498 OSG::UInt32 face_height
= pIn
->getHeight() / 4;
1501 pOut
->set(pIn
->getPixelFormat(),
1514 Real32
*pDst
= reinterpret_cast< Real32
*>(pOut
->editData());
1515 const Real32
*pSrc
= reinterpret_cast<const Real32
*>(pIn
->getData ());
1518 for(OSG::UInt32 j
= 0; j
< face_height
; j
++)
1520 for(OSG::UInt32 i
= 0; i
< face_width
; i
++)
1522 *pDst
++ = pSrc
[(pIn
->getHeight() - (face_height
+ j
+ 1)) * (pIn
->getWidth() * 3) +
1525 *pDst
++ = pSrc
[(pIn
->getHeight() - (face_height
+ j
+ 1)) * (pIn
->getWidth() * 3) +
1528 *pDst
++ = pSrc
[(pIn
->getHeight() - (face_height
+ j
+ 1)) * (pIn
->getWidth() * 3) +
1536 for (OSG::UInt32 j
=0; j
< face_height
; j
++)
1538 for (OSG::UInt32 i
= 0; i
< face_width
; i
++)
1540 *pDst
++ = pSrc
[(pIn
->getHeight() - (face_height
+ j
+ 1)) * (pIn
->getWidth() * 3) +
1541 (2 * face_width
+ i
) * 3 +
1543 *pDst
++ = pSrc
[(pIn
->getHeight() - (face_height
+ j
+ 1)) * (pIn
->getWidth() * 3) +
1544 (2 * face_width
+ i
) * 3 +
1546 *pDst
++ = pSrc
[(pIn
->getHeight() - (face_height
+ j
+ 1)) * (pIn
->getWidth() * 3) +
1547 (2 * face_width
+ i
) * 3 +
1553 OSG::UInt32 uiBaseY
= 3 * face_height
;
1554 OSG::UInt32 uiBaseX
= face_width
;
1556 for(OSG::UInt32 j
= 0; j
< face_height
; ++j
)
1558 for(OSG::UInt32 i
= 0; i
< face_width
; ++i
)
1560 *pDst
++ = pSrc
[(uiBaseY
+ j
) * (pIn
->getWidth() * 3) +
1561 (pIn
->getWidth() - (face_width
+ i
+ 1)) * 3 +
1563 *pDst
++ = pSrc
[(uiBaseY
+ j
) * (pIn
->getWidth() * 3) +
1564 (pIn
->getWidth() - (face_width
+ i
+ 1)) * 3 +
1566 *pDst
++ = pSrc
[(uiBaseY
+ j
) * (pIn
->getWidth() * 3) +
1567 (pIn
->getWidth() - (face_width
+ i
+ 1)) * 3 +
1573 uiBaseY
= face_height
;
1574 uiBaseX
= face_width
;
1576 for(OSG::UInt32 j
= 0; j
< face_height
; ++j
)
1578 for(OSG::UInt32 i
= 0; i
< face_width
; ++i
)
1580 *pDst
++ = pSrc
[(uiBaseY
+ j
) * (pIn
->getWidth() * 3) +
1581 (pIn
->getWidth() - (face_width
+ i
+ 1)) * 3 +
1584 *pDst
++ = pSrc
[(uiBaseY
+ j
) * (pIn
->getWidth() * 3) +
1585 (pIn
->getWidth() - (face_width
+ i
+ 1)) * 3 +
1587 *pDst
++ = pSrc
[(uiBaseY
+ j
) * (pIn
->getWidth() * 3) +
1588 (pIn
->getWidth() - (face_width
+ i
+ 1)) * 3 +
1596 uiBaseX
= face_width
;
1598 for(OSG::UInt32 j
= 0; j
< face_height
; ++j
)
1600 for(OSG::UInt32 i
= 0; i
< face_width
; ++i
)
1602 *pDst
++ = pSrc
[(j
+ 1) * (pIn
->getWidth() * 3) +
1603 (pIn
->getWidth() - (face_width
+ i
+ 1)) * 3 +
1605 *pDst
++ = pSrc
[(j
+ 1) * (pIn
->getWidth() * 3) +
1606 (pIn
->getWidth() - (face_width
+ i
+ 1)) * 3 +
1608 *pDst
++ = pSrc
[(j
+ 1) * (pIn
->getWidth() * 3) +
1609 (pIn
->getWidth() - (face_width
+ i
+ 1)) * 3 +
1615 uiBaseY
= 2 * face_height
;
1616 uiBaseX
= face_width
;
1618 for(OSG::UInt32 j
= 0; j
< face_height
; ++j
)
1620 for(OSG::UInt32 i
= 0; i
< face_width
; ++i
)
1622 *pDst
++ = pSrc
[(pIn
->getHeight() - (face_height
+ j
+ 1)) * (pIn
->getWidth() * 3) +
1625 *pDst
++ = pSrc
[(pIn
->getHeight() - (face_height
+ j
+ 1)) * (pIn
->getWidth() * 3) +
1628 *pDst
++ = pSrc
[(pIn
->getHeight() - (face_height
+ j
+ 1)) * (pIn
->getWidth() * 3) +
1637 ImageTransitPtr
createPerlinImage(const Vec2s
&vSize
,
1638 const Vec2f
&vRange
,
1641 const Vec2f
&vPhase
,
1642 Real32 fPersistance
,
1644 UInt32 uiInterpolMode
,
1646 Image::PixelFormat pixelformat
,
1649 ImageUnrecPtr PerlinImage
= Image::create();
1651 std::vector
<Real32
> ImageData(vSize
.x() * vSize
.y());
1653 bool shouldTranslate
= false;
1657 case Image::OSG_UINT8_IMAGEDATA
:
1658 case Image::OSG_UINT16_IMAGEDATA
:
1659 case Image::OSG_UINT32_IMAGEDATA
:
1660 shouldTranslate
= true;
1663 shouldTranslate
= false;
1667 for(Int32 i
= 0; i
< vSize
.x(); ++i
)
1669 for(Int32 j
= 0; j
< vSize
.y(); ++j
)
1671 ImageData
[i
* vSize
.x() + j
] =
1673 Perlin::calcPerlinNoise(
1674 Pnt2f(vRange
.x() * Real32(i
) / Real32(vSize
.x()),
1675 vRange
.y() * Real32(j
) / Real32(vSize
.y())),
1685 if(shouldTranslate
== true)
1687 ImageData
[i
* vSize
.x() + j
] += 0.5f
;
1692 if(PerlinImage
->set(Image::OSG_I_PF
,
1699 reinterpret_cast<UInt8
*>(&ImageData
[0]),
1700 Image::OSG_FLOAT32_IMAGEDATA
) == true)
1702 if(type
!= Image::OSG_FLOAT32_IMAGEDATA
)
1704 if(PerlinImage
->convertDataTypeTo(type
) == false)
1706 return ImageTransitPtr(NULL
);
1710 if(pixelformat
!= Image::OSG_I_PF
)
1712 if(PerlinImage
->reformat(pixelformat
) == false)
1714 return ImageTransitPtr(NULL
);
1718 return ImageTransitPtr(PerlinImage
);
1722 return ImageTransitPtr(NULL
);
1726 ImageTransitPtr
createPerlinImage(const Vec3s
&vSize
,
1727 const Vec3f
&vRange
,
1730 const Vec3f
&vPhase
,
1731 Real32 fPersistance
,
1733 UInt32 uiInterpolMode
,
1735 Image::PixelFormat pixelformat
,
1738 ImageUnrecPtr PerlinImage
= Image::create();
1740 std::vector
<Real32
> ImageData(vSize
.x() * vSize
.y() * vSize
.z());
1742 bool shouldTranslate
= false;
1746 case Image::OSG_UINT8_IMAGEDATA
:
1747 case Image::OSG_UINT16_IMAGEDATA
:
1748 case Image::OSG_UINT32_IMAGEDATA
:
1749 shouldTranslate
= true;
1752 shouldTranslate
= false;
1756 for(Int32 i
= 0; i
< vSize
.x() ; ++i
)
1758 for(Int32 j
= 0; j
< vSize
.y(); ++j
)
1760 for(Int32 k
= 0; k
< vSize
.z(); ++k
)
1762 ImageData
[i
* vSize
.x() * vSize
.y() + j
* vSize
.y() + k
] =
1765 Perlin::calcPerlinNoise(
1766 Pnt3f(vRange
.x() * Real32(i
) / Real32(vSize
.x()),
1767 vRange
.y() * Real32(j
) / Real32(vSize
.y()),
1768 vRange
.z() * Real32(k
) / Real32(vSize
.z())),
1780 ImageData
[i
* vSize
.x() * vSize
.y() +
1789 if(PerlinImage
->set(Image::OSG_I_PF
,
1796 reinterpret_cast<UInt8
*>(&ImageData
[0]),
1797 Image::OSG_FLOAT32_IMAGEDATA
))
1799 if(type
!= Image::OSG_FLOAT32_IMAGEDATA
)
1801 if(PerlinImage
->convertDataTypeTo(type
) == false)
1803 return ImageTransitPtr(NULL
);
1807 if(pixelformat
!= Image::OSG_I_PF
)
1809 if(PerlinImage
->reformat(pixelformat
) == false)
1811 return ImageTransitPtr(NULL
);
1815 return ImageTransitPtr(PerlinImage
);
1819 return ImageTransitPtr(NULL
);