Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / include / OpenEXR / ImathRandom.h
diff --git a/3rdparty/include/OpenEXR/ImathRandom.h b/3rdparty/include/OpenEXR/ImathRandom.h
new file mode 100644 (file)
index 0000000..4cd44b2
--- /dev/null
@@ -0,0 +1,461 @@
+///////////////////////////////////////////////////////////////////////////
+//
+// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
+// Digital Ltd. LLC
+// 
+// All rights reserved.
+// 
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+// *       Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// *       Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// *       Neither the name of Industrial Light & Magic nor the names of
+// its contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission. 
+// 
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+///////////////////////////////////////////////////////////////////////////
+
+
+#ifndef INCLUDED_IMATHRANDOM_H
+#define INCLUDED_IMATHRANDOM_H
+
+//-----------------------------------------------------------------------------
+//
+//     Generators for uniformly distributed pseudo-random numbers and
+//     functions that use those generators to generate numbers with
+//     different distributions:
+//
+//     class Rand32
+//     class Rand48
+//     solidSphereRand()
+//     hollowSphereRand()
+//     gaussRand()
+//     gaussSphereRand()
+//
+//-----------------------------------------------------------------------------
+
+//
+// Here is the copyright for the *rand48() functions implemented for
+// Windows.
+//
+
+//
+// Copyright (c) 1993 Martin Birgmeier
+// All rights reserved.
+//
+// You may redistribute unmodified or modified versions of this source
+// code provided that the above copyright notice and this and the
+// following conditions are retained.
+//
+// This software is provided ``as is'', and comes with no warranties
+// of any kind. I shall in no event be liable for anything that happens
+// to anyone/anything when using this software.
+//
+
+#include <stdlib.h>
+#include <math.h>
+
+namespace Imath {
+
+
+//-----------------------------------------------
+// Fast random-number generator that generates
+// a uniformly distributed sequence with a period
+// length of 2^32.
+//-----------------------------------------------
+
+class Rand32
+{
+  public:
+
+    //------------
+    // Constructor
+    //------------
+
+    Rand32 (unsigned long int seed = 0);
+    
+
+    //--------------------------------
+    // Re-initialize with a given seed
+    //--------------------------------
+
+    void               init (unsigned long int seed);
+
+
+    //----------------------------------------------------------
+    // Get the next value in the sequence (range: [false, true])
+    //----------------------------------------------------------
+
+    bool               nextb ();
+
+
+    //---------------------------------------------------------------
+    // Get the next value in the sequence (range: [0 ... 0xffffffff])
+    //---------------------------------------------------------------
+
+    unsigned long int  nexti ();
+
+
+    //------------------------------------------------------
+    // Get the next value in the sequence (range: [0 ... 1[)
+    //------------------------------------------------------
+
+    float              nextf ();
+
+
+    //-------------------------------------------------------------------
+    // Get the next value in the sequence (range [rangeMin ... rangeMax[)
+    //-------------------------------------------------------------------
+
+    float              nextf (float rangeMin, float rangeMax);
+
+
+  private:
+
+    void               next ();
+
+    unsigned long int  _state;
+};
+
+
+//--------------------------------------------------------
+// Random-number generator based on the C Standard Library
+// functions drand48(), lrand48() & company; generates a
+// uniformly distributed sequence.
+//--------------------------------------------------------
+
+class Rand48
+{
+  public:
+
+    //------------
+    // Constructor
+    //------------
+
+    Rand48 (unsigned long int seed = 0);
+    
+
+    //--------------------------------
+    // Re-initialize with a given seed
+    //--------------------------------
+
+    void               init (unsigned long int seed);
+
+
+    //----------------------------------------------------------
+    // Get the next value in the sequence (range: [false, true])
+    //----------------------------------------------------------
+
+    bool               nextb ();
+
+
+    //---------------------------------------------------------------
+    // Get the next value in the sequence (range: [0 ... 0x7fffffff])
+    //---------------------------------------------------------------
+
+    long int           nexti ();
+
+
+    //------------------------------------------------------
+    // Get the next value in the sequence (range: [0 ... 1[)
+    //------------------------------------------------------
+
+    double             nextf ();
+
+
+    //-------------------------------------------------------------------
+    // Get the next value in the sequence (range [rangeMin ... rangeMax[)
+    //-------------------------------------------------------------------
+
+    double             nextf (double rangeMin, double rangeMax);
+
+
+  private:
+
+    unsigned short int _state[3];
+    
+#if defined ( _WIN32 ) || defined ( _WIN64 ) || defined ( __MWERKS__ )
+    void               shiftState();
+#endif
+};
+
+
+//------------------------------------------------------------
+// Return random points uniformly distributed in a sphere with
+// radius 1 around the origin (distance from origin <= 1).
+//------------------------------------------------------------
+
+template <class Vec, class Rand>
+Vec            
+solidSphereRand (Rand &rand);
+
+
+//-------------------------------------------------------------
+// Return random points uniformly distributed on the surface of
+// a sphere with radius 1 around the origin.
+//-------------------------------------------------------------
+
+template <class Vec, class Rand>
+Vec            
+hollowSphereRand (Rand &rand);
+
+
+//-----------------------------------------------
+// Return random numbers with a normal (Gaussian)
+// distribution with zero mean and unit variance.
+//-----------------------------------------------
+
+template <class Rand>
+float
+gaussRand (Rand &rand);
+
+
+//----------------------------------------------------
+// Return random points whose distance from the origin
+// has a normal (Gaussian) distribution with zero mean
+// and unit variance.
+//----------------------------------------------------
+
+template <class Vec, class Rand>
+Vec
+gaussSphereRand (Rand &rand);
+
+
+//---------------
+// Implementation
+//---------------
+
+
+inline void
+Rand32::init (unsigned long int seed)
+{
+    _state = (seed * 0xa5a573a5L) ^ 0x5a5a5a5aL;
+}
+
+
+inline
+Rand32::Rand32 (unsigned long int seed)
+{
+    init (seed);
+}
+
+
+inline void
+Rand32::next ()
+{
+    _state = 1664525L * _state + 1013904223L;
+}
+
+
+inline bool
+Rand32::nextb ()
+{
+    next ();
+    // Return the 31st (most significant) bit, by and-ing with 2 ^ 31.
+    return !!(_state & 2147483648UL);
+}
+
+
+inline unsigned long int
+Rand32::nexti ()
+{
+    next ();
+    return _state & 0xffffffff;
+}
+
+
+inline float
+Rand32::nextf ()
+{
+    next ();
+    return ((int) (_state & 0xffffff)) * ((float) (1.0F / 0x1000000));
+}
+
+
+inline float
+Rand32::nextf (float rangeMin, float rangeMax)
+{
+    return rangeMin + nextf() * (rangeMax - rangeMin);
+}
+
+
+inline void
+Rand48::init (unsigned long int seed)
+{
+    seed = (seed * 0xa5a573a5L) ^ 0x5a5a5a5aL;
+
+    _state[0] = (unsigned short int) (seed);
+    _state[1] = (unsigned short int) (seed >> 16);
+    _state[2] = (unsigned short int) (seed);
+}
+
+
+inline 
+Rand48::Rand48 (unsigned long int seed)
+{
+    init (seed);
+}
+
+
+#if defined ( _WIN32 ) || defined ( _WIN64 ) || defined ( __MWERKS__ )
+
+inline void
+Rand48::shiftState()
+{
+    unsigned long   accu;
+    unsigned short  temp[2];
+
+    accu = 0xe66dUL * ( unsigned long )_state[0] + 0x000bUL;
+
+    temp[0] = ( unsigned short )accu;  /* lower 16 bits */
+    accu >>= sizeof( unsigned short ) * 8;
+
+    accu += 0xe66dUL * ( unsigned long )_state[1] +
+           0xdeecUL * ( unsigned long )_state[0];
+
+    temp[1] = ( unsigned short )accu;  /* middle 16 bits */
+    accu >>= sizeof( unsigned short ) * 8;
+
+    accu += 0xe66dUL * _state[2] +
+           0xdeecUL * _state[1] +
+           0x0005UL * _state[0];
+
+    _state[0] = temp[0];
+    _state[1] = temp[1];
+    _state[2] = ( unsigned short )accu;
+}
+
+#endif
+
+inline bool
+Rand48::nextb ()
+{
+#if defined ( _WIN32 ) || defined ( _WIN64 ) || defined ( __MWERKS__ )
+    shiftState();
+    return ( ( long( _state[2] ) << 15 ) + ( long( _state[1] ) >> 1 ) ) & 0x1;
+#else
+    return nrand48 (_state) & 1;
+#endif
+}
+
+
+inline long int
+Rand48::nexti ()
+{
+#if defined ( _WIN32 ) || defined ( _WIN64 ) || defined ( __MWERKS__ )
+    shiftState();
+    return ( long( _state[2] ) << 15 ) + ( long( _state[1] ) >> 1 );
+#else
+    return nrand48 (_state);
+#endif
+}
+
+
+inline double
+Rand48::nextf ()
+{
+#if defined ( _WIN32 ) || defined ( _WIN64 ) || defined ( __MWERKS__ )
+    shiftState();
+    return ldexp( double( _state[0] ), -48 ) +
+          ldexp( double( _state[1] ), -32 ) +
+          ldexp( double( _state[2] ), -16 );
+#else
+    return erand48 (_state);
+#endif
+}
+
+
+inline double
+Rand48::nextf (double rangeMin, double rangeMax)
+{
+    return rangeMin + nextf() * (rangeMax - rangeMin);
+}
+
+
+template <class Vec, class Rand>
+Vec
+solidSphereRand (Rand &rand)
+{
+    Vec v;
+
+    do
+    {
+       for (unsigned int i = 0; i < Vec::dimensions(); i++)
+           v[i] = (typename Vec::BaseType) rand.nextf (-1, 1);
+    }
+    while (v.length2() > 1);
+
+    return v;
+}
+
+
+template <class Vec, class Rand>
+Vec
+hollowSphereRand (Rand &rand)
+{
+    Vec v;
+    typename Vec::BaseType length;
+
+    do
+    {
+       for (unsigned int i = 0; i < Vec::dimensions(); i++)
+           v[i] = (typename Vec::BaseType) rand.nextf (-1, 1);
+
+       length = v.length();
+    }
+    while (length > 1 || length == 0);
+
+    return v / length;
+}
+
+
+template <class Rand>
+float
+gaussRand (Rand &rand)
+{
+    float x;           // Note: to avoid numerical problems with very small
+    float y;           // numbers, we make these variables singe-precision
+    float length2;     // floats, but later we call the double-precision log()
+                       // and sqrt() functions instead of logf() and sqrtf().
+    do
+    {
+       x = float (rand.nextf (-1, 1));
+       y = float (rand.nextf (-1, 1));
+       length2 = x * x + y * y;
+    }
+    while (length2 >= 1 || length2 == 0);
+
+    return x * sqrt (-2 * log (length2) / length2);
+}
+
+
+template <class Vec, class Rand>
+Vec
+gaussSphereRand (Rand &rand)
+{
+    return hollowSphereRand <Vec> (rand) * gaussRand (rand);
+}
+
+double drand48();
+long int lrand48();
+
+} // namespace Imath
+
+#endif