// noiseutils.h
//
// Copyright (C) 2003-2005 Jason Bevins
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or (at
// your option) any later version.
//
// This library is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
// License (COPYING.txt) for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with this library; if not, write to the Free Software Foundation,
// Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//
// The developer's email is jlbezigvins@gmzigail.com (for great email, take
// off every 'zig'.)
//

#ifndef NOISEUTILS_H
#define NOISEUTILS_H

#include <stdlib.h>
#include <string.h>
#include <string>

#include <libnoise/noise.h>

using namespace noise;

namespace noise
{

  namespace utils
  {

    /// @mainpage noiseutils
    ///
    /// @section intro Introduction
    ///
    /// This library contains useful classes for creating and rendering
    /// two-dimensional noise maps containing coherent noise that was
    /// generated from the libnoise library.  These classes are used to create
    /// procedural textures and terrain height maps.
    ///
    /// noiseutils is known to compile under Windows 2000 Service Pack 4
    /// (using Microsoft Visual C++ 5.0) and under Gentoo Linux 10.0 (using
    /// gcc 3.3.4).  It should be portable across all platforms that can
    /// compile libnoise.
    ///
    /// @section classes Classes
    ///
    /// This library contains the following classes:
    /// - A <i>noise map</i> class: This class implements a two-dimensional
    ///   array that stores floating-point values.  It's designed to store
    ///   coherent-noise values generated by a noise module.
    /// - Several <i>noise-map builder</i> classes: Each of these classes
    ///   fills a noise map with coherent-noise values generated by a noise
    ///   module.  While filling a noise map, it iterates the coordinates of
    ///   the input value along the surface of a specific mathematical object.
    ///   Each of these classes implements a different mathematical object,
    ///   such as a plane, a cylinder, or a sphere.
    /// - An <i>image</i> class: This class implements a two-dimensional array
    ///   that stores color values.
    /// - Several <i>image-renderer</i> classes: these classes render images
    ///   given the contents of a noise map.  Each of these classes renders an
    ///   image in a different way.
    ///
    /// @section contact Contact
    ///
    /// Contact jas for questions about noiseutils.  The spam-resistant email
    /// address is jlbezigvins@gmzigail.com (For great email, take off every
    /// <a href=http://www.planettribes.com/allyourbase/story.shtml>zig</a>.)

    /// The maximum width of a raster.
    const int RASTER_MAX_WIDTH = 32767;

    /// The maximum height of a raster.
    const int RASTER_MAX_HEIGHT = 32767;

    #ifndef DOXYGEN_SHOULD_SKIP_THIS
    // The raster's stride length must be a multiple of this constant.
    const int RASTER_STRIDE_BOUNDARY = 4;
    #endif

    /// A pointer to a callback function used by the NoiseMapBuilder class.
    ///
    /// The NoiseMapBuilder::Build() method calls this callback function each
    /// time it fills a row of the noise map with coherent-noise values.
    ///
    /// This callback function has a single integer parameter that contains
    /// a count of the rows that have been completed.  It returns void.  Pass
    /// a function with this signature to the NoiseMapBuilder::SetCallback()
    /// method.
    typedef void(*NoiseMapCallback) (int row);

    /// Number of meters per point in a Terragen terrain (TER) file.
    const double DEFAULT_METERS_PER_POINT = 30.0;

    /// Same as the DEFAULT_METERS_PER_POINT constant, but for us
    /// canuckleheads.
    const double DEFAULT_METRES_PER_POINT = DEFAULT_METERS_PER_POINT;

    /// Defines a color.
    ///
    /// A color object contains four 8-bit channels: red, green, blue, and an
    /// alpha (transparency) channel.  Channel values range from 0 to 255.
    ///
    /// The alpha channel defines the transparency of the color.  If the alpha
    /// channel has a value of 0, the color is completely transparent.  If the
    /// alpha channel has a value of 255, the color is completely opaque.
    class Color
    {

      public:

        /// Constructor.
        Color ()
        {
        }

        /// Constructor.
        ///
        /// @param r Value of the red channel.
        /// @param g Value of the green channel.
        /// @param b Value of the blue channel.
        /// @param a Value of the alpha (transparency) channel.
        Color (noise::uint8 r, noise::uint8 g, noise::uint8 b,
          noise::uint8 a):
          red (r), green (g), blue (b), alpha (a)
        {
        }

        /// Value of the alpha (transparency) channel.
        noise::uint8 alpha;

        /// Value of the blue channel.
        noise::uint8 blue;

        /// Value of the green channel.
        noise::uint8 green;

        /// Value of the red channel.
        noise::uint8 red;

    };

    /// Defines a point used to build a color gradient.
    ///
    /// A color gradient is a list of gradually-changing colors.  A color
    /// gradient is defined by a list of <i>gradient points</i>.  Each
    /// gradient point has a position and a color.  In a color gradient, the
    /// colors between two adjacent gradient points are linearly interpolated.
    ///
    /// The ColorGradient class defines a color gradient by a list of these
    /// objects.
    struct GradientPoint
    {

      /// The position of this gradient point.
      double pos;

      /// The color of this gradient point.
      Color color;

    };

    /// Defines a color gradient.
    ///
    /// A color gradient is a list of gradually-changing colors.  A color
    /// gradient is defined by a list of <i>gradient points</i>.  Each
    /// gradient point has a position and a color.  In a color gradient, the
    /// colors between two adjacent gradient points are linearly interpolated.
    ///
    /// To add a gradient point to the color gradient, pass its position and
    /// color to the AddGradientPoint() method.
    ///
    /// To retrieve a color from a specific position in the color gradient,
    /// pass that position to the GetColor() method.
    ///
    /// This class is a useful tool for coloring height maps based on
    /// elevation.
    ///
    /// <b>Gradient example</b>
    ///
    /// Suppose a gradient object contains the following gradient points:
    /// - -1.0 maps to black.
    /// - 0.0 maps to white.
    /// - 1.0 maps to red.
    ///
    /// If an application passes -0.5 to the GetColor() method, this method
    /// will return a gray color that is halfway between black and white.
    ///
    /// If an application passes 0.25 to the GetColor() method, this method
    /// will return a very light pink color that is one quarter of the way
    /// between white and red.
    class GradientColor
    {

      public:

        /// Constructor.
        GradientColor ();

        /// Destructor.
        ~GradientColor ();

        /// Adds a gradient point to this gradient object.
        ///
        /// @param gradientPos The position of this gradient point.
        /// @param gradientColor The color of this gradient point.
        ///
        /// @pre No two gradient points have the same position.
        ///
        /// @throw noise::ExceptionInvalidParam See the precondition.
        ///
        /// It does not matter which order these gradient points are added.
        void AddGradientPoint (double gradientPos,
          const Color& gradientColor);

        /// Deletes all the gradient points from this gradient object.
        ///
        /// @post All gradient points from this gradient object are deleted.
        void Clear ();

        /// Returns the color at the specified position in the color gradient.
        ///
        /// @param gradientPos The specified position.
        ///
        /// @returns The color at that position.
        const Color& GetColor (double gradientPos) const;

        /// Returns a pointer to the array of gradient points in this object.
        ///
        /// @returns A pointer to the array of gradient points.
        ///
        /// Before calling this method, call GetGradientPointCount() to
        /// determine the number of gradient points in this array.
        ///
        /// It is recommended that an application does not store this pointer
        /// for later use since the pointer to the array may change if the
        /// application calls another method of this object.
        const GradientPoint* GetGradientPointArray () const
        {
          return m_pGradientPoints;
        }

        /// Returns the number of gradient points stored in this object.
        ///
        /// @returns The number of gradient points stored in this object.
        int GetGradientPointCount () const
        {
          return m_gradientPointCount;
        }

      private:

        /// Determines the array index in which to insert the gradient point
        /// into the internal gradient-point array.
        ///
        /// @param gradientPos The position of this gradient point.
        ///
        /// @returns The array index in which to insert the gradient point.
        ///
        /// @pre No two gradient points have the same input value.
        ///
        /// @throw noise::ExceptionInvalidParam See the precondition.
        ///
        /// By inserting the gradient point at the returned array index, this
        /// object ensures that the gradient-point array is sorted by input
        /// value.  The code that maps a value to a color requires a sorted
        /// gradient-point array.
        int FindInsertionPos (double gradientPos);

        /// Inserts the gradient point at the specified position in the
        /// internal gradient-point array.
        ///
        /// @param insertionPos The zero-based array position in which to
        /// insert the gradient point.
        /// @param gradientPos The position of this gradient point.
        /// @param gradientColor The color of this gradient point.
        ///
        /// To make room for this new gradient point, this method reallocates
        /// the gradient-point array and shifts all gradient points occurring
        /// after the insertion position up by one.
        ///
        /// Because this object requires that all gradient points in the array
        /// must be sorted by the position, the new gradient point should be
        /// inserted at the position in which the order is still preserved.
        void InsertAtPos (int insertionPos, double gradientPos,
          const Color& gradientColor);

        /// Number of gradient points.
        int m_gradientPointCount;

        /// Array that stores the gradient points.
        GradientPoint* m_pGradientPoints;

        /// A color object that is used by a gradient object to store a
        /// temporary value.
        mutable Color m_workingColor;
    };

    /// Implements a noise map, a 2-dimensional array of floating-point
    /// values.
    ///
    /// A noise map is designed to store coherent-noise values generated by a
    /// noise module, although it can store values from any source.  A noise
    /// map is often used as a terrain height map or a grayscale texture.
    ///
    /// The size (width and height) of the noise map can be specified during
    /// object construction or at any other time.
    ///
    /// The GetValue() and SetValue() methods can be used to access individual
    /// values stored in the noise map.
    ///
    /// This class manages its own memory.  If you copy a noise map object
    /// into another noise map object, the original contents of the noise map
    /// object will be freed.
    ///
    /// If you specify a new size for the noise map and the new size is
    /// smaller than the current size, the allocated memory will not be
    /// reallocated.
    /// Call ReclaimMem() to reclaim the wasted memory.
    ///
    /// <b>Border Values</b>
    ///
    /// All of the values outside of the noise map are assumed to have a
    /// common value known as the <i>border value</i>.
    ///
    /// To set the border value, call the SetBorderValue() method.
    ///
    /// The GetValue() method returns the border value if the specified value
    /// lies outside of the noise map.
    ///
    /// <b>Internal Noise Map Structure</b>
    ///
    /// Internally, the values are organized into horizontal rows called @a
    /// slabs.  Slabs are ordered from bottom to top.
    ///
    /// Each slab contains a contiguous row of values in memory.  The values
    /// in a slab are organized left to right.
    ///
    /// The offset between the starting points of any two adjacent slabs is
    /// called the <i>stride amount</i>.  The stride amount is measured by
    /// the number of @a float values between these two starting points, not
    /// by the number of bytes.  For efficiency reasons, the stride is often a
    /// multiple of the machine word size.
    ///
    /// The GetSlabPtr() and GetConstSlabPtr() methods allow you to retrieve
    /// pointers to the slabs themselves.
    class NoiseMap
    {

      public:

        /// Constructor.
        ///
        /// Creates an empty noise map.
        NoiseMap ();

        /// Constructor.
        ///
        /// @param width The width of the new noise map.
        /// @param height The height of the new noise map.
        ///
        /// @pre The width and height values are positive.
        /// @pre The width and height values do not exceed the maximum
        /// possible width and height for the noise map.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        ///
        /// Creates a noise map with uninitialized values.
        ///
        /// It is considered an error if the specified dimensions are not
        /// positive.
        NoiseMap (int width, int height);

        /// Copy constructor.
        ///
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        NoiseMap (const NoiseMap& rhs);

        /// Destructor.
        ///
        /// Frees the allocated memory for the noise map.
        ~NoiseMap ();

        /// Assignment operator.
        ///
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        ///
        /// @returns Reference to self.
        ///
        /// Creates a copy of the noise map.
        NoiseMap& operator= (const NoiseMap& rhs);

        /// Clears the noise map to a specified value.
        ///
        /// @param value The value that all positions within the noise map are
        /// cleared to.
        void Clear (float value);

        /// Returns the value used for all positions outside of the noise map.
        ///
        /// @returns The value used for all positions outside of the noise
        /// map.
        ///
        /// All positions outside of the noise map are assumed to have a
        /// common value known as the <i>border value</i>.
        float GetBorderValue () const
        {
          return m_borderValue;
        }

        /// Returns a const pointer to a slab.
        ///
        /// @returns A const pointer to a slab at the position (0, 0), or
        /// @a NULL if the noise map is empty.
        const float* GetConstSlabPtr () const
        {
          return m_pNoiseMap;
        }

        /// Returns a const pointer to a slab at the specified row.
        ///
        /// @param row The row, or @a y coordinate.
        ///
        /// @returns A const pointer to a slab at the position ( 0, @a row ),
        /// or @a NULL if the noise map is empty.
        ///
        /// @pre The coordinates must exist within the bounds of the noise
        /// map.
        ///
        /// This method does not perform bounds checking so be careful when
        /// calling it.
        const float* GetConstSlabPtr (int row) const
        {
          return GetConstSlabPtr (0, row);
        }

        /// Returns a const pointer to a slab at the specified position.
        ///
        /// @param x The x coordinate of the position.
        /// @param y The y coordinate of the position.
        ///
        /// @returns A const pointer to a slab at the position ( @a x, @a y ),
        /// or @a NULL if the noise map is empty.
        ///
        /// @pre The coordinates must exist within the bounds of the noise
        /// map.
        ///
        /// This method does not perform bounds checking so be careful when
        /// calling it.
        const float* GetConstSlabPtr (int x, int y) const
        {
          return m_pNoiseMap + (size_t)x + (size_t)m_stride * (size_t)y;
        }

        /// Returns the height of the noise map.
        ///
        /// @returns The height of the noise map.
        int GetHeight () const
        {
          return m_height;
        }

        /// Returns the amount of memory allocated for this noise map.
        ///
        /// @returns The amount of memory allocated for this noise map.
        ///
        /// This method returns the number of @a float values allocated.
        size_t GetMemUsed () const
        {
          return m_memUsed;
        }

        /// Returns a pointer to a slab.
        ///
        /// @returns A pointer to a slab at the position (0, 0), or @a NULL if
        /// the noise map is empty.
        float* GetSlabPtr ()
        {
          return m_pNoiseMap;
        }

        /// Returns a pointer to a slab at the specified row.
        ///
        /// @param row The row, or @a y coordinate.
        ///
        /// @returns A pointer to a slab at the position ( 0, @a row ), or
        /// @a NULL if the noise map is empty.
        ///
        /// @pre The coordinates must exist within the bounds of the noise
        /// map.
        ///
        /// This method does not perform bounds checking so be careful when
        /// calling it.
        float* GetSlabPtr (int row)
        {
          return GetSlabPtr (0, row);
        }

        /// Returns a pointer to a slab at the specified position.
        ///
        /// @param x The x coordinate of the position.
        /// @param y The y coordinate of the position.
        ///
        /// @returns A pointer to a slab at the position ( @a x, @a y ) or
        /// @a NULL if the noise map is empty.
        ///
        /// @pre The coordinates must exist within the bounds of the noise
        /// map.
        ///
        /// This method does not perform bounds checking so be careful when
        /// calling it.
        float* GetSlabPtr (int x, int y)
        {
          return m_pNoiseMap + (size_t)x + (size_t)m_stride * (size_t)y;
        }

        /// Returns the stride amount of the noise map.
        ///
        /// @returns The stride amount of the noise map.
        ///
        /// - The <i>stride amount</i> is the offset between the starting
        ///   points of any two adjacent slabs in a noise map.
        /// - The stride amount is measured by the number of @a float values
        ///   between these two points, not by the number of bytes.
        int GetStride () const
        {
          return m_stride;
        }

        /// Returns a value from the specified position in the noise map.
        ///
        /// @param x The x coordinate of the position.
        /// @param y The y coordinate of the position.
        ///
        /// @returns The value at that position.
        ///
        /// This method returns the border value if the coordinates exist
        /// outside of the noise map.
        float GetValue (int x, int y) const;

        /// Returns the width of the noise map.
        ///
        /// @returns The width of the noise map.
        int GetWidth () const
        {
          return m_width;
        }

        /// Reallocates the noise map to recover wasted memory.
        ///
        /// @throw noise::ExceptionOutOfMemory Out of memory.  (Yes, this
        /// method can return an out-of-memory exception because two noise
        /// maps will temporarily exist in memory during this call.)
        ///
        /// The contents of the noise map is unaffected.
        void ReclaimMem ();

        /// Sets the value to use for all positions outside of the noise map.
        ///
        /// @param borderValue The value to use for all positions outside of
        /// the noise map.
        ///
        /// All positions outside of the noise map are assumed to have a
        /// common value known as the <i>border value</i>.
        void SetBorderValue (float borderValue)
        {
          m_borderValue = borderValue;
        }

        /// Sets the new size for the noise map.
        ///
        /// @param width The new width for the noise map.
        /// @param height The new height for the noise map.
        ///
        /// @pre The width and height values are positive.
        /// @pre The width and height values do not exceed the maximum
        /// possible width and height for the noise map.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        ///
        /// On exit, the contents of the noise map are undefined.
        ///
        /// If the @a OUT_OF_MEMORY exception occurs, this noise map object
        /// becomes empty.
        ///
        /// If the @a INVALID_PARAM exception occurs, the noise map is
        /// unmodified.
        void SetSize (int width, int height);

        /// Sets a value at a specified position in the noise map.
        ///
        /// @param x The x coordinate of the position.
        /// @param y The y coordinate of the position.
        /// @param value The value to set at the given position.
        ///
        /// This method does nothing if the noise map object is empty or the
        /// position is outside the bounds of the noise map.
        void SetValue (int x, int y, float value);

        /// Takes ownership of the buffer within the source noise map.
        ///
        /// @param source The source noise map.
        ///
        /// On exit, the source noise map object becomes empty.
        ///
        /// This method only moves the buffer pointer so this method is very
        /// quick.
        void TakeOwnership (NoiseMap& source);

      private:

        /// Returns the minimum amount of memory required to store a noise map
        /// of the specified size.
        ///
        /// @param width The width of the noise map.
        /// @param height The height of the noise map.
        ///
        /// @returns The minimum amount of memory required to store the noise
        /// map.
        ///
        /// The returned value is measured by the number of @a float values
        /// required to store the noise map, not by the number of bytes.
        size_t CalcMinMemUsage (int width, int height) const
        {
          return CalcStride ((size_t)width) * (size_t)height;
        }

        /// Calculates the stride amount for a noise map.
        ///
        /// @param width The width of the noise map.
        ///
        /// @returns The stride amount.
        ///
        /// - The <i>stride amount</i> is the offset between the starting
        ///   points of any two adjacent slabs in a noise map.
        /// - The stride amount is measured by the number of @a float values
        ///   between these two points, not by the number of bytes.
        size_t CalcStride (int width) const
        {
          return (size_t)(((width + RASTER_STRIDE_BOUNDARY - 1)
            / RASTER_STRIDE_BOUNDARY) * RASTER_STRIDE_BOUNDARY);
        }

        /// Copies the contents of the buffer in the source noise map into
        /// this noise map.
        ///
        /// @param source The source noise map.
        ///
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        ///
        /// This method reallocates the buffer in this noise map object if
        /// necessary.
        ///
        /// @warning This method calls the standard library function
        /// @a memcpy, which probably violates the DMCA because it can be used
        //. to make a bitwise copy of anything, like, say, a DVD.  Don't call
        /// this method if you live in the USA.
        void CopyNoiseMap (const NoiseMap& source);

        /// Resets the noise map object.
        ///
        /// This method is similar to the InitObj() method, except this method
        /// deletes the buffer in this noise map.
        void DeleteNoiseMapAndReset ();

        /// Initializes the noise map object.
        ///
        /// @pre Must be called during object construction.
        /// @pre The noise map buffer must not exist.
        void InitObj ();

        /// Value used for all positions outside of the noise map.
        float m_borderValue;

        /// The current height of the noise map.
        int m_height;

        /// The amount of memory allocated for this noise map.
        ///
        /// This value is equal to the number of @a float values allocated for
        /// the noise map, not the number of bytes.
        size_t m_memUsed;

        /// A pointer to the noise map buffer.
        float* m_pNoiseMap;

        /// The stride amount of the noise map.
        int m_stride;

        /// The current width of the noise map.
        int m_width;

    };

    /// Implements an image, a 2-dimensional array of color values.
    ///
    /// An image can be used to store a color texture.
    ///
    /// These color values are of type Color.
    ///
    /// The size (width and height) of the image can be specified during
    /// object construction or at any other time.
    ///
    /// The GetValue() and SetValue() methods can be used to access individual
    /// color values stored in the image.
    ///
    /// This class manages its own memory.  If you copy an image object into
    /// another image object, the original contents of the image object will
    /// be freed.
    ///
    /// If you specify a new size for the image and the new size is smaller
    /// than the current size, the allocated memory will not be reallocated.
    /// Call ReclaimMem() to reclaim the wasted memory.
    ///
    /// <b>Border Values</b>
    ///
    /// All of the color values outside of the image are assumed to have a
    /// common color value known as the <i>border value</i>.
    ///
    /// To set the border value, call the SetBorderValue() method.
    ///
    /// The GetValue() method returns the border value if the specified
    /// position lies outside of the image.
    ///
    /// <b>Internal Image Structure</b>
    ///
    /// Internally, the color values are organized into horizontal rows called
    /// @a slabs.  Slabs are ordered from bottom to top.
    ///
    /// Each slab contains a contiguous row of color values in memory.  The
    /// color values in a slab are organized left to right.  These values are
    /// of type Color.
    ///
    /// The offset between the starting points of any two adjacent slabs is
    /// called the <i>stride amount</i>.  The stride amount is measured by the
    /// number of Color objects between these two starting points, not by the
    /// number of bytes.  For efficiency reasons, the stride is often a
    /// multiple of the machine word size.
    ///
    /// The GetSlabPtr() methods allow you to retrieve pointers to the slabs
    /// themselves.
    class Image
    {

      public:

        /// Constructor.
        ///
        /// Creates an empty image.
        Image ();

        /// Constructor.
        ///
        /// @param width The width of the new image.
        /// @param height The height of the new image.
        ///
        /// @pre The width and height values are positive.
        /// @pre The width and height values do not exceed the maximum
        /// possible width and height for the image.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        ///
        /// Creates an image with uninitialized color values.
        ///
        /// It is considered an error if the specified dimensions are not
        /// positive.
        Image (int width, int height);

        /// Copy constructor.
        ///
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        Image  (const Image& rhs);

        /// Destructor.
        ///
        /// Frees the allocated memory for the image.
        ~Image ();

        /// Assignment operator.
        ///
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        ///
        /// @returns Reference to self.
        ///
        /// Creates a copy of the image.
        Image& operator= (const Image& rhs);

        /// Clears the image to a specified color value.
        ///
        /// @param value The color value that all positions within the image
        /// are cleared to.
        void Clear (const Color& value);

        /// Returns the color value used for all positions outside of the
        /// image.
        ///
        /// @returns The color value used for all positions outside of the
        /// image.
        ///
        /// All positions outside of the image are assumed to have a common
        /// color value known as the <i>border value</i>.
        Color GetBorderValue () const
        {
          return m_borderValue;
        }

        /// Returns a const pointer to a slab.
        ///
        /// @returns A const pointer to a slab at the position (0, 0), or
        /// @a NULL if the image is empty.
        const Color* GetConstSlabPtr () const
        {
          return m_pImage;
        }

        /// Returns a const pointer to a slab at the specified row.
        ///
        /// @param row The row, or @a y coordinate.
        ///
        /// @returns A const pointer to a slab at the position ( 0, @a row ),
        /// or @a NULL if the image is empty.
        ///
        /// @pre The coordinates must exist within the bounds of the image.
        ///
        /// This method does not perform bounds checking so be careful when
        /// calling it.
        const Color* GetConstSlabPtr (int row) const
        {
          return GetConstSlabPtr (0, row);
        }

        /// Returns a const pointer to a slab at the specified position.
        ///
        /// @param x The x coordinate of the position.
        /// @param y The y coordinate of the position.
        ///
        /// @returns A const pointer to a slab at the position ( @a x, @a y ),
        /// or @a NULL if the image is empty.
        ///
        /// @pre The coordinates must exist within the bounds of the image.
        ///
        /// This method does not perform bounds checking so be careful when
        /// calling it.
        const Color* GetConstSlabPtr (int x, int y) const
        {
          return m_pImage + (size_t)x + (size_t)m_stride * (size_t)y;
        }

        /// Returns the height of the image.
        ///
        /// @returns The height of the image.
        int GetHeight () const
        {
          return m_height;
        }

        /// Returns the amount of memory allocated for this image.
        ///
        /// @returns The amount of memory allocated for this image.
        ///
        /// This method returns the number of Color objects allocated.
        size_t GetMemUsed () const
        {
          return m_memUsed;
        }

        /// Returns a pointer to a slab.
        ///
        /// @returns A pointer to a slab at the position (0, 0), or @a NULL if
        /// the image is empty.
        Color* GetSlabPtr ()
        {
          return m_pImage;
        }

        /// Returns a pointer to a slab at the specified row.
        ///
        /// @param row The row, or @a y coordinate.
        ///
        /// @returns A pointer to a slab at the position ( 0, @a row ), or
        /// @a NULL if the image is empty.
        ///
        /// @pre The coordinates must exist within the bounds of the image.
        ///
        /// This method does not perform bounds checking so be careful when
        /// calling it.
        Color* GetSlabPtr (int row)
        {
          return GetSlabPtr (0, row);
        }

        /// Returns a pointer to a slab at the specified position.
        ///
        /// @param x The x coordinate of the position.
        /// @param y The y coordinate of the position.
        ///
        /// @returns A pointer to a slab at the position ( @a x, @a y ), or
        /// @a NULL if the image is empty.
        ///
        /// @pre The coordinates must exist within the bounds of the image.
        ///
        /// This method does not perform bounds checking so be careful when
        /// calling it.
        Color* GetSlabPtr (int x, int y)
        {
          return m_pImage + (size_t)x + (size_t)m_stride * (size_t)y;
        }

        /// Returns the stride amount of the image.
        ///
        /// @returns The stride amount of the image.
        ///
        /// - The <i>stride amount</i> is the offset between the starting
        ///   points of any two adjacent slabs in an image.
        /// - The stride amount is measured by the number of Color objects
        ///   between these two points, not by the number of bytes.
        int GetStride () const
        {
          return m_stride;
        }

        /// Returns a color value from the specified position in the image.
        ///
        /// @param x The x coordinate of the position.
        /// @param y The y coordinate of the position.
        ///
        /// @returns The color value at that position.
        ///
        /// This method returns the border value if the coordinates exist
        /// outside of the image.
        Color GetValue (int x, int y) const;

        /// Returns the width of the image.
        ///
        /// @returns The width of the image.
        int GetWidth () const
        {
          return m_width;
        }

        /// Reallocates the image to recover wasted memory.
        ///
        /// @throw noise::ExceptionOutOfMemory Out of memory.  (Yes, this
        /// method can return an out-of-memory exception because two images
        /// will exist temporarily in memory during this call.)
        ///
        /// The contents of the image is unaffected.
        void ReclaimMem ();

        /// Sets the color value to use for all positions outside of the
        /// image.
        ///
        /// @param borderValue The color value to use for all positions
        /// outside of the image.
        ///
        /// All positions outside of the image are assumed to have a common
        /// color value known as the <i>border value</i>.
        void SetBorderValue (const Color& borderValue)
        {
          m_borderValue = borderValue;
        }

        /// Sets the new size for the image.
        ///
        /// @param width The new width for the image.
        /// @param height The new height for the image.
        ///
        /// @pre The width and height values are positive.
        /// @pre The width and height values do not exceed the maximum
        /// possible width and height for the image.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        ///
        /// On exit, the contents of the image are undefined.
        ///
        /// If the @a OUT_OF_MEMORY exception occurs, this image becomes
        /// empty.
        ///
        /// If the @a INVALID_PARAM exception occurs, the image is unmodified.
        void SetSize (int width, int height);

        /// Sets a color value at a specified position in the image.
        ///
        /// @param x The x coordinate of the position.
        /// @param y The y coordinate of the position.
        /// @param value The color value to set at the given position.
        ///
        /// This method does nothing if the image is empty or the position is
        /// outside the bounds of the image.
        void SetValue (int x, int y, const Color& value);

        /// Takes ownership of the buffer within the source image.
        ///
        /// @param source The source image.
        ///
        /// On exit, the source image object becomes empty.
        ///
        /// This method only moves the buffer pointer so this method is very
        /// quick.
        void TakeOwnership (Image& source);

      private:

        /// Returns the minimum amount of memory required to store an image of
        /// the specified size.
        ///
        /// @param width The width of the image.
        /// @param height The height of the image.
        ///
        /// @returns The minimum amount of memory required to store the image.
        ///
        /// The returned color value is measured by the number of Color
        /// objects required to store the image, not by the number of bytes.
        size_t CalcMinMemUsage (int width, int height) const
        {
          return CalcStride ((size_t)width) * (size_t)height;
        }

        /// Calculates the stride amount for an image.
        ///
        /// @param width The width of the image.
        ///
        /// @returns The stride amount.
        ///
        /// - The <i>stride amount</i> is the offset between the starting
        ///   points of any two adjacent slabs in an image.
        /// - The stride amount is measured by the number of Color objects
        ///   between these two points, not by the number of bytes.
        size_t CalcStride (int width) const
        {
          return (size_t)(((width + RASTER_STRIDE_BOUNDARY - 1)
            / RASTER_STRIDE_BOUNDARY) * RASTER_STRIDE_BOUNDARY);
        }

        /// Copies the contents of the buffer in the source image into this
        /// image.
        ///
        /// @param source The source image.
        ///
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        ///
        /// This method reallocates the buffer in this image object if
        /// necessary.
        ///
        /// @warning This method calls the standard library function
        /// @a memcpy, which probably violates the DMCA because it can be used
        /// to make a bitwise copy of anything, like, say, a DVD.  Don't call
        /// this method if you live in the USA.
        void CopyImage (const Image& source);

        /// Resets the image object.
        ///
        /// This method is similar to the InitObj() method, except this method
        /// deletes the memory allocated to the image.
        void DeleteImageAndReset ();

        /// Initializes the image object.
        ///
        /// @pre Must be called during object construction.
        /// @pre The image buffer must not exist.
        void InitObj ();

        /// The Color value used for all positions outside of the image.
        Color m_borderValue;

        /// The current height of the image.
        int m_height;

        /// The amount of memory allocated for the image.
        ///
        /// This value is equal to the number of Color objects allocated for
        /// the image, not the number of bytes.
        size_t m_memUsed;

        /// A pointer to the image buffer.
        Color* m_pImage;

        /// The stride amount of the image.
        int m_stride;

        /// The current width of the image.
        int m_width;

    };

    /// Windows bitmap image writer class.
    ///
    /// This class creates a file in Windows bitmap (*.bmp) format given the
    /// contents of an image object.
    ///
    /// <b>Writing the image</b>
    ///
    /// To write the image to a file, perform the following steps:
    /// - Pass the filename to the SetDestFilename() method.
    /// - Pass an Image object to the SetSourceImage() method.
    /// - Call the WriteDestFile() method.
    ///
    /// The SetDestFilename() and SetSourceImage() methods must be called
    /// before calling the WriteDestFile() method.
    class WriterBMP
    {

      public:

        /// Constructor.
        WriterBMP ():
          m_pSourceImage (NULL)
        {
        }

        /// Returns the name of the file to write.
        ///
        /// @returns The name of the file to write.
        std::string GetDestFilename () const
        {
          return m_destFilename;
        }

        /// Sets the name of the file to write.
        ///
        /// @param filename The name of the file to write.
        ///
        /// Call this method before calling the WriteDestFile() method.
        void SetDestFilename (const std::string& filename)
        {
          m_destFilename = filename;
        }

        /// Sets the image object that is written to the file.
        ///
        /// @param sourceImage The image object to write.
        ///
        /// This object only stores a pointer to an image object, so make sure
        /// this object exists before calling the WriteDestFile() method.
        void SetSourceImage (Image& sourceImage)
        {
          m_pSourceImage = &sourceImage;
        }

        /// Writes the contents of the image object to the file.
        ///
        /// @pre SetDestFilename() has been previously called.
        /// @pre SetSourceImage() has been previously called.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        /// @throw noise::ExceptionUnknown An unknown exception occurred.
        /// Possibly the file could not be written.
        ///
        /// This method encodes the contents of the image and writes it to a
        /// file.  Before calling this method, call the SetSourceImage()
        /// method to specify the image, then call the SetDestFilename()
        /// method to specify the name of the file to write.
        void WriteDestFile ();

      protected:

        /// Calculates the width of one horizontal line in the file, in bytes.
        ///
        /// @param width The width of the image, in points.
        ///
        /// @returns The width of one horizontal line in the file.
        ///
        /// Windows bitmap files require that the width of one horizontal line
        /// must be aligned to a 32-bit boundary.
        int CalcWidthByteCount (int width) const;

        /// Name of the file to write.
        std::string m_destFilename;

        /// A pointer to the image object that will be written to the file.
        Image* m_pSourceImage;

    };

    /// Terragen Terrain writer class.
    ///
    /// This class creates a file in Terrage Terrain (*.ter) format given the
    /// contents of a noise map object.  This class treats the values in the
    /// noise map as elevations measured in meters.
    ///
    /// <a href=http://www.planetside.co.uk/terragen/>Terragen</a> is a
    /// terrain application that renders realistic landscapes.  Terragen is
    /// available for Windows and MacOS; unfortunately, Terragen does not have
    /// UN*X versions.
    ///
    /// <b>Writing the noise map</b>
    ///
    /// To write the noise map, perform the following steps:
    /// - Pass the filename to the SetDestFilename() method.
    /// - Pass a NoiseMap object to the SetSourceNoiseMap() method.
    /// - Call the WriteDestFile() method.
    ///
    /// The SetDestFilename() and SetSourceNoiseMap() methods must be called
    /// before calling the WriteDestFile() method.
    class WriterTER
    {

      public:

        /// Constructor.
        WriterTER ():
          m_pSourceNoiseMap (NULL),
          m_metersPerPoint (DEFAULT_METERS_PER_POINT)
        {
        }

        /// Returns the name of the file to write.
        ///
        /// @returns The name of the file to write.
        std::string GetDestFilename () const
        {
          return m_destFilename;
        }

        /// Returns the distance separating adjacent points in the noise map,
        /// in meters.
        ///
        /// @returns The distance separating adjacent points in the noise map.
        float GetMetersPerPoint () const
        {
          return m_metersPerPoint;
        }

        /// Sets the name of the file to write.
        ///
        /// @param filename The name of the file to write.
        ///
        /// Call this method before calling the WriteDestFile() method.
        void SetDestFilename (const std::string& filename)
        {
          m_destFilename = filename;
        }

        /// Sets the distance separating adjacent points in the noise map, in
        /// meters.
        ///
        /// @param metersPerPoint The distance separating adjacent points in
        /// the noise map.
        void SetMetersPerPoint (float metersPerPoint)
        {
          m_metersPerPoint = metersPerPoint;
        }

        /// Sets the noise map object that is written to the file.
        ///
        /// @param sourceNoiseMap The noise map object to write.
        ///
        /// This object only stores a pointer to a noise map object, so make
        /// sure this object exists before calling the WriteDestFile() method.
        void SetSourceNoiseMap (NoiseMap& sourceNoiseMap)
        {
          m_pSourceNoiseMap = &sourceNoiseMap;
        }

        /// Writes the contents of the noise map object to the file.
        ///
        /// @pre SetDestFilename() has been previously called.
        /// @pre SetSourceNoiseMap() has been previously called.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        /// @throw noise::ExceptionUnknown An unknown exception occurred.
        /// Possibly the file could not be written.
        ///
        /// This method encodes the contents of the noise map and writes it to
        /// a file.  Before calling this method, call the SetSourceNoiseMap()
        /// method to specify the noise map, then call the SetDestFilename()
        /// method to specify the name of the file to write.
        ///
        /// This object assumes that the noise values represent elevations in
        /// meters.
        void WriteDestFile ();

      protected:

        /// Calculates the width of one horizontal line in the file, in bytes.
        ///
        /// @param width The width of the noise map, in points.
        ///
        /// @returns The width of one horizontal line in the file.
        int CalcWidthByteCount (int width) const;

        /// Name of the file to write.
        std::string m_destFilename;

        /// The distance separating adjacent points in the noise map, in
        /// meters.
        float m_metersPerPoint;

        /// A pointer to the noise map that will be written to the file.
        NoiseMap* m_pSourceNoiseMap;

    };

    /// Abstract base class for a noise-map builder
    ///
    /// A builder class builds a noise map by filling it with coherent-noise
    /// values generated from the surface of a three-dimensional mathematical
    /// object.  Each builder class defines a specific three-dimensional
    /// surface, such as a cylinder, sphere, or plane.
    ///
    /// A builder class describes these input values using a coordinate system
    /// applicable for the mathematical object (e.g., a latitude/longitude
    /// coordinate system for the spherical noise-map builder.)  It then
    /// "flattens" these coordinates onto a plane so that it can write the
    /// coherent-noise values into a two-dimensional noise map.
    ///
    /// <b>Building the Noise Map</b>
    ///
    /// To build the noise map, perform the following steps:
    /// - Pass the bounding coordinates to the SetBounds() method.
    /// - Pass the noise map size, in points, to the SetDestSize() method.
    /// - Pass a NoiseMap object to the SetDestNoiseMap() method.
    /// - Pass a noise module (derived from noise::module::Module) to the
    ///   SetSourceModule() method.
    /// - Call the Build() method.
    ///
    /// You may also pass a callback function to the SetCallback() method.
    /// The Build() method calls this callback function each time it fills a
    /// row of the noise map with coherent-noise values.  This callback
    /// function has a single integer parameter that contains a count of the
    /// rows that have been completed.  It returns void.
    ///
    /// Note that SetBounds() is not defined in the abstract base class; it is
    /// only defined in the derived classes.  This is because each model uses
    /// a different coordinate system.
    class NoiseMapBuilder
    {

      public:

        /// Constructor.
        NoiseMapBuilder ();

        /// Builds the noise map.
        ///
        /// @pre SetBounds() was previously called.
        /// @pre SetDestNoiseMap() was previously called.
        /// @pre SetSourceModule() was previously called.
        /// @pre The width and height values specified by SetDestSize() are
        /// positive.
        /// @pre The width and height values specified by SetDestSize() do not
        /// exceed the maximum possible width and height for the noise map.
        ///
        /// @post The original contents of the destination noise map is
        /// destroyed.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        /// @throw noise::ExceptionOutOfMemory Out of memory.
        ///
        /// If this method is successful, the destination noise map contains
        /// the coherent-noise values from the noise module specified by
        /// SetSourceModule().
        virtual void Build () = 0;

        /// Returns the height of the destination noise map.
        ///
        /// @returns The height of the destination noise map, in points.
        ///
        /// This object does not change the height in the destination noise
        /// map object until the Build() method is called.
        double GetDestHeight () const
        {
          return m_destHeight;
        }

        /// Returns the width of the destination noise map.
        ///
        /// @returns The width of the destination noise map, in points.
        ///
        /// This object does not change the height in the destination noise
        /// map object until the Build() method is called.
        double GetDestWidth () const
        {
          return m_destWidth;
        }

        /// Sets the callback function that Build() calls each time it fills a
        /// row of the noise map with coherent-noise values.
        ///
        /// @param pCallback The callback function.
        ///
        /// This callback function has a single integer parameter that
        /// contains a count of the rows that have been completed.  It returns
        /// void.  Pass a function with this signature to the SetCallback()
        /// method.
        void SetCallback (NoiseMapCallback pCallback);

        /// Sets the destination noise map.
        ///
        /// @param destNoiseMap The destination noise map.
        ///
        /// The destination noise map will contain the coherent-noise values
        /// from this noise map after a successful call to the Build() method.
        ///
        /// The destination noise map must exist throughout the lifetime of
        /// this object unless another noise map replaces that noise map.
        void SetDestNoiseMap (NoiseMap& destNoiseMap)
        {
          m_pDestNoiseMap = &destNoiseMap;
        }

        /// Sets the source module.
        ///
        /// @param sourceModule The source module.
        ///
        /// This object fills in a noise map with the coherent-noise values
        /// from this source module.
        ///
        /// The source module must exist throughout the lifetime of this
        /// object unless another noise module replaces that noise module.
        void SetSourceModule (const module::Module& sourceModule)
        {
          m_pSourceModule = &sourceModule;
        }

        /// Sets the size of the destination noise map.
        ///
        /// @param destWidth The width of the destination noise map, in
        /// points.
        /// @param destHeight The height of the destination noise map, in
        /// points.
        ///
        /// This method does not change the size of the destination noise map
        /// until the Build() method is called.
        void SetDestSize (int destWidth, int destHeight)
        {
          m_destWidth  = destWidth ;
          m_destHeight = destHeight;
        }

      protected:

        /// The callback function that Build() calls each time it fills a row
        /// of the noise map with coherent-noise values.
        ///
        /// This callback function has a single integer parameter that
        /// contains a count of the rows that have been completed.  It returns
        /// void.  Pass a function with this signature to the SetCallback()
        /// method.
        NoiseMapCallback m_pCallback;

        /// Height of the destination noise map, in points.
        int m_destHeight;

        /// Width of the destination noise map, in points.
        int m_destWidth;

        /// Destination noise map that will contain the coherent-noise values.
        NoiseMap* m_pDestNoiseMap;

        /// Source noise module that will generate the coherent-noise values.
        const module::Module* m_pSourceModule;

    };

    /// Builds a cylindrical noise map.
    ///
    /// This class builds a noise map by filling it with coherent-noise values
    /// generated from the surface of a cylinder.
    ///
    /// This class describes these input values using an (angle, height)
    /// coordinate system.  After generating the coherent-noise value from the
    /// input value, it then "flattens" these coordinates onto a plane so that
    /// it can write the values into a two-dimensional noise map.
    ///
    /// The cylinder model has a radius of 1.0 unit and has infinite height.
    /// The cylinder is oriented along the @a y axis.  Its center is at the
    /// origin.
    ///
    /// The x coordinate in the noise map represents the angle around the
    /// cylinder's y axis.  The y coordinate in the noise map represents the
    /// height above the x-z plane.
    ///
    /// The application must provide the lower and upper angle bounds of the
    /// noise map, in degrees, and the lower and upper height bounds of the
    /// noise map, in units.
    class NoiseMapBuilderCylinder: public NoiseMapBuilder
    {

      public:

        /// Constructor.
        NoiseMapBuilderCylinder ();

        virtual void Build ();

        /// Returns the lower angle boundary of the cylindrical noise map.
        ///
        /// @returns The lower angle boundary of the noise map, in degrees.
        double GetLowerAngleBound () const
        {
          return m_lowerAngleBound;
        }

        /// Returns the lower height boundary of the cylindrical noise map.
        ///
        /// @returns The lower height boundary of the noise map, in units.
        ///
        /// One unit is equal to the radius of the cylinder.
        double GetLowerHeightBound () const
        {
          return m_lowerHeightBound;
        }

        /// Returns the upper angle boundary of the cylindrical noise map.
        ///
        /// @returns The upper angle boundary of the noise map, in degrees.
        double GetUpperAngleBound () const
        {
          return m_upperAngleBound;
        }

        /// Returns the upper height boundary of the cylindrical noise map.
        ///
        /// @returns The upper height boundary of the noise map, in units.
        ///
        /// One unit is equal to the radius of the cylinder.
        double GetUpperHeightBound () const
        {
          return m_upperHeightBound;
        }

        /// Sets the coordinate boundaries of the noise map.
        ///
        /// @param lowerAngleBound The lower angle boundary of the noise map,
        /// in degrees.
        /// @param upperAngleBound The upper angle boundary of the noise map,
        /// in degrees.
        /// @param lowerHeightBound The lower height boundary of the noise
        /// map, in units.
        /// @param upperHeightBound The upper height boundary of the noise
        /// map, in units.
        ///
        /// @pre The lower angle boundary is less than the upper angle
        /// boundary.
        /// @pre The lower height boundary is less than the upper height
        /// boundary.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        ///
        /// One unit is equal to the radius of the cylinder.
        void SetBounds (double lowerAngleBound, double upperAngleBound,
          double lowerHeightBound, double upperHeightBound)
        {
          if (lowerAngleBound >= upperAngleBound
            || lowerHeightBound >= upperHeightBound) {
            throw noise::ExceptionInvalidParam ();
          }

          m_lowerAngleBound  = lowerAngleBound ;
          m_upperAngleBound  = upperAngleBound ;
          m_lowerHeightBound = lowerHeightBound;
          m_upperHeightBound = upperHeightBound;
        }

      private:

        /// Lower angle boundary of the cylindrical noise map, in degrees.
        double m_lowerAngleBound;

        /// Lower height boundary of the cylindrical noise map, in units.
        double m_lowerHeightBound;

        /// Upper angle boundary of the cylindrical noise map, in degrees.
        double m_upperAngleBound;

        /// Upper height boundary of the cylindrical noise map, in units.
        double m_upperHeightBound;

    };

    /// Builds a planar noise map.
    ///
    /// This class builds a noise map by filling it with coherent-noise values
    /// generated from the surface of a plane.
    ///
    /// This class describes these input values using (x, z) coordinates.
    /// Their y coordinates are always 0.0.
    ///
    /// The application must provide the lower and upper x coordinate bounds
    /// of the noise map, in units, and the lower and upper z coordinate
    /// bounds of the noise map, in units.
    ///
    /// To make a tileable noise map with no seams at the edges, call the
    /// EnableSeamless() method.
    class NoiseMapBuilderPlane: public NoiseMapBuilder
    {

      public:

        /// Constructor.
        NoiseMapBuilderPlane ();

        virtual void Build ();

        /// Enables or disables seamless tiling.
        ///
        /// @param enable A flag that enables or disables seamless tiling.
        ///
        /// Enabling seamless tiling builds a noise map with no seams at the
        /// edges.  This allows the noise map to be tileable.
        void EnableSeamless (bool enable = true)
        {
          m_isSeamlessEnabled = enable;
        }

        /// Returns the lower x boundary of the planar noise map.
        ///
        /// @returns The lower x boundary of the planar noise map, in units.
        double GetLowerXBound () const
        {
          return m_lowerXBound;
        }

        /// Returns the lower z boundary of the planar noise map.
        ///
        /// @returns The lower z boundary of the noise map, in units.
        double GetLowerZBound () const
        {
          return m_lowerZBound;
        }

        /// Returns the upper x boundary of the planar noise map.
        ///
        /// @returns The upper x boundary of the noise map, in units.
        double GetUpperXBound () const
        {
          return m_upperXBound;
        }

        /// Returns the upper z boundary of the planar noise map.
        ///
        /// @returns The upper z boundary of the noise map, in units.
        double GetUpperZBound () const
        {
          return m_upperZBound;
        }

        /// Determines if seamless tiling is enabled.
        ///
        /// @returns
        /// - @a true if seamless tiling is enabled.
        /// - @a false if seamless tiling is disabled.
        ///
        /// Enabling seamless tiling builds a noise map with no seams at the
        /// edges.  This allows the noise map to be tileable.
        bool IsSeamlessEnabled () const
        {
          return m_isSeamlessEnabled;
        }

        /// Sets the boundaries of the planar noise map.
        ///
        /// @param lowerXBound The lower x boundary of the noise map, in
        /// units.
        /// @param upperXBound The upper x boundary of the noise map, in
        /// units.
        /// @param lowerZBound The lower z boundary of the noise map, in
        /// units.
        /// @param upperZBound The upper z boundary of the noise map, in
        /// units.
        ///
        /// @pre The lower x boundary is less than the upper x boundary.
        /// @pre The lower z boundary is less than the upper z boundary.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        void SetBounds (double lowerXBound, double upperXBound,
          double lowerZBound, double upperZBound)
        {
          if (lowerXBound >= upperXBound
            || lowerZBound >= upperZBound) {
            throw noise::ExceptionInvalidParam ();
          }

          m_lowerXBound = lowerXBound;
          m_upperXBound = upperXBound;
          m_lowerZBound = lowerZBound;
          m_upperZBound = upperZBound;
        }

      private:

        /// A flag specifying whether seamless tiling is enabled.
        bool m_isSeamlessEnabled;

        /// Lower x boundary of the planar noise map, in units.
        double m_lowerXBound;

        /// Lower z boundary of the planar noise map, in units.
        double m_lowerZBound;

        /// Upper x boundary of the planar noise map, in units.
        double m_upperXBound;

        /// Upper z boundary of the planar noise map, in units.
        double m_upperZBound;

    };


    /// Builds a spherical noise map.
    ///
    /// This class builds a noise map by filling it with coherent-noise values
    /// generated from the surface of a sphere.
    ///
    /// This class describes these input values using a (latitude, longitude)
    /// coordinate system.  After generating the coherent-noise value from the
    /// input value, it then "flattens" these coordinates onto a plane so that
    /// it can write the values into a two-dimensional noise map.
    ///
    /// The sphere model has a radius of 1.0 unit.  Its center is at the
    /// origin.
    ///
    /// The x coordinate in the noise map represents the longitude.  The y
    /// coordinate in the noise map represents the latitude.
    ///
    /// The application must provide the southern, northern, western, and
    /// eastern bounds of the noise map, in degrees.
    class NoiseMapBuilderSphere: public NoiseMapBuilder
    {

      public:

        /// Constructor.
        NoiseMapBuilderSphere ();

        virtual void Build ();

        /// Returns the eastern boundary of the spherical noise map.
        ///
        /// @returns The eastern boundary of the noise map, in degrees.
        double GetEastLonBound () const
        {
          return m_eastLonBound;
        }

        /// Returns the northern boundary of the spherical noise map
        ///
        /// @returns The northern boundary of the noise map, in degrees.
        double GetNorthLatBound () const
        {
          return m_northLatBound;
        }

        /// Returns the southern boundary of the spherical noise map
        ///
        /// @returns The southern boundary of the noise map, in degrees.
        double GetSouthLatBound () const
        {
          return m_southLatBound;
        }

        /// Returns the western boundary of the spherical noise map
        ///
        /// @returns The western boundary of the noise map, in degrees.
        double GetWestLonBound () const
        {
          return m_westLonBound;
        }

        /// Sets the coordinate boundaries of the noise map.
        ///
        /// @param southLatBound The southern boundary of the noise map, in
        /// degrees.
        /// @param northLatBound The northern boundary of the noise map, in
        /// degrees.
        /// @param westLonBound The western boundary of the noise map, in
        /// degrees.
        /// @param eastLonBound The eastern boundary of the noise map, in
        /// degrees.
        ///
        /// @pre The southern boundary is less than the northern boundary.
        /// @pre The western boundary is less than the eastern boundary.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        void SetBounds (double southLatBound, double northLatBound,
          double westLonBound, double eastLonBound)
        {
          if (southLatBound >= northLatBound
            || westLonBound >= eastLonBound) {
            throw noise::ExceptionInvalidParam ();
          }

          m_southLatBound = southLatBound;
          m_northLatBound = northLatBound;
          m_westLonBound  = westLonBound ;
          m_eastLonBound  = eastLonBound ;
        }

      private:

        /// Eastern boundary of the spherical noise map, in degrees.
        double m_eastLonBound;

        /// Northern boundary of the spherical noise map, in degrees.
        double m_northLatBound;

        /// Southern boundary of the spherical noise map, in degrees.
        double m_southLatBound;

        /// Western boundary of the spherical noise map, in degrees.
        double m_westLonBound;

    };

    /// Renders an image from a noise map.
    ///
    /// This class renders an image given the contents of a noise-map object.
    ///
    /// An application can configure the output of the image in three ways:
    /// - Specify the color gradient.
    /// - Specify the light source parameters.
    /// - Specify the background image.
    ///
    /// <b>Specify the color gradient</b>
    ///
    /// This class uses a color gradient to calculate the color for each pixel
    /// in the destination image according to the value from the corresponding
    /// position in the noise map.
    ///
    /// A color gradient is a list of gradually-changing colors.  A color
    /// gradient is defined by a list of <i>gradient points</i>.  Each
    /// gradient point has a position and a color.  In a color gradient, the
    /// colors between two adjacent gradient points are linearly interpolated.
    ///
    /// For example, suppose this class contains the following color gradient:
    ///
    /// - -1.0 maps to dark blue.
    /// - -0.2 maps to light blue.
    /// - -0.1 maps to tan.
    /// - 0.0 maps to green.
    /// - 1.0 maps to white.
    ///
    /// The value 0.5 maps to a greenish-white color because 0.5 is halfway
    /// between 0.0 (mapped to green) and 1.0 (mapped to white).
    ///
    /// The value -0.6 maps to a medium blue color because -0.6 is halfway
    /// between -1.0 (mapped to dark blue) and -0.2 (mapped to light blue).
    ///
    /// The color gradient requires a minimum of two gradient points.
    ///
    /// This class contains two pre-made gradients: a grayscale gradient and a
    /// color gradient suitable for terrain.  To use these pre-made gradients,
    /// call the BuildGrayscaleGradient() or BuildTerrainGradient() methods,
    /// respectively.
    ///
    /// @note The color value passed to AddGradientPoint() has an alpha
    /// channel.  This alpha channel specifies how a pixel in the background
    /// image (if specified) is blended with the calculated color.  If the
    /// alpha value is high, this class weighs the blend towards the
    /// calculated color, and if the alpha value is low, this class weighs the
    /// blend towards the color from the corresponding pixel in the background
    /// image.
    ///
    /// <b>Specify the light source parameters</b>
    ///
    /// This class contains a parallel light source that lights the image.  It
    /// interprets the noise map as a bump map.
    ///
    /// To enable or disable lighting, pass a Boolean value to the
    /// EnableLight() method.
    ///
    /// To set the position of the light source in the "sky", call the
    /// SetLightAzimuth() and SetLightElev() methods.
    ///
    /// To set the color of the light source, call the SetLightColor() method.
    ///
    /// To set the intensity of the light source, call the SetLightIntensity()
    /// method.  A good intensity value is 2.0, although that value tends to
    /// "wash out" very light colors from the image.
    ///
    /// To set the contrast amount between areas in light and areas in shadow,
    /// call the SetLightContrast() method.  Determining the correct contrast
    /// amount requires some trial and error, but if your application
    /// interprets the noise map as a height map that has its elevation values
    /// measured in meters and has a horizontal resolution of @a h meters, a
    /// good contrast amount to use is ( 1.0 / @a h ).
    ///
    /// <b>Specify the background image</b>
    ///
    /// To specify a background image, pass an Image object to the
    /// SetBackgroundImage() method.
    ///
    /// This class determines the color of a pixel in the destination image by
    /// blending the calculated color with the color of the corresponding
    /// pixel from the background image.
    ///
    /// The blend amount is determined by the alpha of the calculated color.
    /// If the alpha value is high, this class weighs the blend towards the
    /// calculated color, and if the alpha value is low, this class weighs the
    /// blend towards the color from the corresponding pixel in the background
    /// image.
    ///
    /// <b>Rendering the image</b>
    ///
    /// To render the image, perform the following steps:
    /// - Pass a NoiseMap object to the SetSourceNoiseMap() method.
    /// - Pass an Image object to the SetDestImage() method.
    /// - Pass an Image object to the SetBackgroundImage() method (optional)
    /// - Call the Render() method.
    class RendererImage
    {

      public:

        /// Constructor.
        RendererImage ();

        /// Adds a gradient point to this gradient object.
        ///
        /// @param gradientPos The position of this gradient point.
        /// @param gradientColor The color of this gradient point.
        ///
        /// @pre No two gradient points have the same position.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        ///
        /// This object uses a color gradient to calculate the color for each
        /// pixel in the destination image according to the value from the
        /// corresponding position in the noise map.
        ///
        /// The gradient requires a minimum of two gradient points.
        ///
        /// The specified color value passed to this method has an alpha
        /// channel.  This alpha channel specifies how a pixel in the
        /// background image (if specified) is blended with the calculated
        /// color.  If the alpha value is high, this object weighs the blend
        /// towards the calculated color, and if the alpha value is low, this
        /// object weighs the blend towards the color from the corresponding
        /// pixel in the background image.
        void AddGradientPoint (double gradientPos,
          const Color& gradientColor);

        /// Builds a grayscale gradient.
        ///
        /// @post The original gradient is cleared and a grayscale gradient is
        /// created.
        ///
        /// This color gradient contains the following gradient points:
        /// - -1.0 maps to black
        /// - 1.0 maps to white
        void BuildGrayscaleGradient ();

        /// Builds a color gradient suitable for terrain.
        ///
        /// @post The original gradient is cleared and a terrain gradient is
        /// created.
        ///
        /// This gradient color at position 0.0 is the "sea level".  Above
        /// that value, the gradient contains greens, browns, and whites.
        /// Below that value, the gradient contains various shades of blue.
        void BuildTerrainGradient ();

        /// Clears the color gradient.
        ///
        /// Before calling the Render() method, the application must specify a
        /// new color gradient with at least two gradient points.
        void ClearGradient ();

        /// Enables or disables the light source.
        ///
        /// @param enable A flag that enables or disables the light source.
        ///
        /// If the light source is enabled, this object will interpret the
        /// noise map as a bump map.
        void EnableLight (bool enable = true)
        {
          m_isLightEnabled = enable;
        }

        /// Enables or disables noise-map wrapping.
        ///
        /// @param enable A flag that enables or disables noise-map wrapping.
        ///
        /// This object requires five points (the initial point and its four
        /// neighbors) to calculate light shading.  If wrapping is enabled,
        /// and the initial point is on the edge of the noise map, the
        /// appropriate neighbors that lie outside of the noise map will
        /// "wrap" to the opposite side(s) of the noise map.  Otherwise, the
        /// appropriate neighbors are cropped to the edge of the noise map.
        ///
        /// Enabling wrapping is useful when creating spherical renderings and
        /// tileable textures.
        void EnableWrap (bool enable = true)
        {
          m_isWrapEnabled = enable;
        }

        /// Returns the azimuth of the light source, in degrees.
        ///
        /// @returns The azimuth of the light source.
        ///
        /// The azimuth is the location of the light source around the
        /// horizon:
        /// - 0.0 degrees is east.
        /// - 90.0 degrees is north.
        /// - 180.0 degrees is west.
        /// - 270.0 degrees is south.
        double GetLightAzimuth () const
        {
          return m_lightAzimuth;
        }

        /// Returns the brightness of the light source.
        ///
        /// @returns The brightness of the light source.
        double GetLightBrightness () const
        {
          return m_lightBrightness;
        }

        /// Returns the color of the light source.
        ///
        /// @returns The color of the light source.
        Color GetLightColor () const
        {
          return m_lightColor;
        }

        /// Returns the contrast of the light source.
        ///
        /// @returns The contrast of the light source.
        ///
        /// The contrast specifies how sharp the boundary is between the
        /// light-facing areas and the shadowed areas.
        ///
        /// The contrast determines the difference between areas in light and
        /// areas in shadow.  Determining the correct contrast amount requires
        /// some trial and error, but if your application interprets the noise
        /// map as a height map that has a spatial resolution of @a h meters
        /// and an elevation resolution of 1 meter, a good contrast amount to
        /// use is ( 1.0 / @a h ).
        double GetLightContrast () const
        {
          return m_lightContrast;
        }

        /// Returns the elevation of the light source, in degrees.
        ///
        /// @returns The elevation of the light source.
        ///
        /// The elevation is the angle above the horizon:
        /// - 0 degrees is on the horizon.
        /// - 90 degrees is straight up.
        double GetLightElev () const
        {
          return m_lightElev;
        }

        /// Returns the intensity of the light source.
        ///
        /// @returns The intensity of the light source.
        double GetLightIntensity () const
        {
          return m_lightIntensity;
        }

        /// Determines if the light source is enabled.
        ///
        /// @returns
        /// - @a true if the light source is enabled.
        /// - @a false if the light source is disabled.
        bool IsLightEnabled () const
        {
          return m_isLightEnabled;
        }

        /// Determines if noise-map wrapping is enabled.
        ///
        /// @returns
        /// - @a true if noise-map wrapping is enabled.
        /// - @a false if noise-map wrapping is disabled.
        ///
        /// This object requires five points (the initial point and its four
        /// neighbors) to calculate light shading.  If wrapping is enabled,
        /// and the initial point is on the edge of the noise map, the
        /// appropriate neighbors that lie outside of the noise map will
        /// "wrap" to the opposite side(s) of the noise map.  Otherwise, the
        /// appropriate neighbors are cropped to the edge of the noise map.
        ///
        /// Enabling wrapping is useful when creating spherical renderings and
        /// tileable textures
        bool IsWrapEnabled () const
        {
          return m_isWrapEnabled;
        }

        /// Renders the destination image using the contents of the source
        /// noise map and an optional background image.
        ///
        /// @pre SetSourceNoiseMap() has been previously called.
        /// @pre SetDestImage() has been previously called.
        /// @pre There are at least two gradient points in the color gradient.
        /// @pre No two gradient points have the same position.
        /// @pre If a background image was specified, it has the exact same
        /// size as the source height map.
        ///
        /// @post The original contents of the destination image is destroyed.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        ///
        /// The background image and the destination image can safely refer to
        /// the same image, although in this case, the destination image is
        /// irretrievably blended into the background image.
        void Render ();

        /// Sets the background image.
        ///
        /// @param backgroundImage The background image.
        ///
        /// If a background image has been specified, the Render() method
        /// blends the pixels from the background image onto the corresponding
        /// pixels in the destination image.  The blending weights are
        /// determined by the alpha channel in the pixels in the destination
        /// image.
        ///
        /// The destination image must exist throughout the lifetime of this
        /// object unless another image replaces that image.
        void SetBackgroundImage (const Image& backgroundImage)
        {
          m_pBackgroundImage = &backgroundImage;
        }

        /// Sets the destination image.
        ///
        /// @param destImage The destination image.
        ///
        /// The destination image will contain the rendered image after a
        /// successful call to the Render() method.
        ///
        /// The destination image must exist throughout the lifetime of this
        /// object unless another image replaces that image.
        void SetDestImage (Image& destImage)
        {
          m_pDestImage = &destImage;
        }

        /// Sets the azimuth of the light source, in degrees.
        ///
        /// @param lightAzimuth The azimuth of the light source.
        ///
        /// The azimuth is the location of the light source around the
        /// horizon:
        /// - 0.0 degrees is east.
        /// - 90.0 degrees is north.
        /// - 180.0 degrees is west.
        /// - 270.0 degrees is south.
        ///
        /// Make sure the light source is enabled via a call to the
        /// EnableLight() method before calling the Render() method.
        void SetLightAzimuth (double lightAzimuth)
        {
          m_lightAzimuth = lightAzimuth;
          m_recalcLightValues = true;
        }

        /// Sets the brightness of the light source.
        ///
        /// @param lightBrightness The brightness of the light source.
        ///
        /// Make sure the light source is enabled via a call to the
        /// EnableLight() method before calling the Render() method.
        void SetLightBrightness (double lightBrightness)
        {
          m_lightBrightness = lightBrightness;
          m_recalcLightValues = true;
        }

        /// Sets the color of the light source.
        ///
        /// @param lightColor The light color.
        ///
        /// Make sure the light source is enabled via a call to the
        /// EnableLight() method before calling the Render() method.
        void SetLightColor (const Color& lightColor)
        {
          m_lightColor = lightColor;
        }

        /// Sets the contrast of the light source.
        ///
        /// @param lightContrast The contrast of the light source.
        ///
        /// @pre The specified light contrast is positive.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        ///
        /// The contrast specifies how sharp the boundary is between the
        /// light-facing areas and the shadowed areas.
        ///
        /// The contrast determines the difference between areas in light and
        /// areas in shadow.  Determining the correct contrast amount requires
        /// some trial and error, but if your application interprets the noise
        /// map as a height map that has a spatial resolution of @a h meters
        /// and an elevation resolution of 1 meter, a good contrast amount to
        /// use is ( 1.0 / @a h ).
        ///
        /// Make sure the light source is enabled via a call to the
        /// EnableLight() method before calling the Render() method.
        void SetLightContrast (double lightContrast)
        {
          if (lightContrast <= 0.0) {
            throw noise::ExceptionInvalidParam ();
          }

          m_lightContrast = lightContrast;
          m_recalcLightValues = true;
        }

        /// Sets the elevation of the light source, in degrees.
        ///
        /// @param lightElev The elevation of the light source.
        ///
        /// The elevation is the angle above the horizon:
        /// - 0 degrees is on the horizon.
        /// - 90 degrees is straight up.
        ///
        /// Make sure the light source is enabled via a call to the
        /// EnableLight() method before calling the Render() method.
        void SetLightElev (double lightElev)
        {
          m_lightElev = lightElev;
          m_recalcLightValues = true;
        }

        /// Returns the intensity of the light source.
        ///
        /// @returns The intensity of the light source.
        ///
        /// A good value for intensity is 2.0.
        ///
        /// Make sure the light source is enabled via a call to the
        /// EnableLight() method before calling the Render() method.
        void SetLightIntensity (double lightIntensity)
        {
          if (lightIntensity < 0.0) {
            throw noise::ExceptionInvalidParam ();
          }

          m_lightIntensity = lightIntensity;
          m_recalcLightValues = true;
        }

        /// Sets the source noise map.
        ///
        /// @param sourceNoiseMap The source noise map.
        ///
        /// The destination image must exist throughout the lifetime of this
        /// object unless another image replaces that image.
        void SetSourceNoiseMap (const NoiseMap& sourceNoiseMap)
        {
          m_pSourceNoiseMap = &sourceNoiseMap;
        }

      private:

        /// Calculates the destination color.
        ///
        /// @param sourceColor The source color generated from the color
        /// gradient.
        /// @param backgroundColor The color from the background image at the
        /// corresponding position.
        /// @param lightValue The intensity of the light at that position.
        ///
        /// @returns The destination color.
        Color CalcDestColor (const Color& sourceColor,
          const Color& backgroundColor, double lightValue) const;

        /// Calculates the intensity of the light given some elevation values.
        ///
        /// @param center Elevation of the center point.
        /// @param left Elevation of the point directly left of the center
        /// point.
        /// @param right Elevation of the point directly right of the center
        /// point.
        /// @param down Elevation of the point directly below the center
        /// point.
        /// @param up Elevation of the point directly above the center point.
        ///
        /// These values come directly from the noise map.
        double CalcLightIntensity (double center, double left, double right,
          double down, double up) const;

        /// The cosine of the azimuth of the light source.
        mutable double m_cosAzimuth;

        /// The cosine of the elevation of the light source.
        mutable double m_cosElev;

        /// The color gradient used to specify the image colors.
        GradientColor m_gradient;

        /// A flag specifying whether lighting is enabled.
        bool m_isLightEnabled;

        /// A flag specifying whether wrapping is enabled.
        bool m_isWrapEnabled;

        /// The azimuth of the light source, in degrees.
        double m_lightAzimuth;

        /// The brightness of the light source.
        double m_lightBrightness;

        /// The color of the light source.
        Color m_lightColor;

        /// The contrast between areas in light and areas in shadow.
        double m_lightContrast;

        /// The elevation of the light source, in degrees.
        double m_lightElev;

        /// The intensity of the light source.
        double m_lightIntensity;

        /// A pointer to the background image.
        const Image* m_pBackgroundImage;

        /// A pointer to the destination image.
        Image* m_pDestImage;

        /// A pointer to the source noise map.
        const NoiseMap* m_pSourceNoiseMap;

        /// Used by the CalcLightIntensity() method to recalculate the light
        /// values only if the light parameters change.
        ///
        /// When the light parameters change, this value is set to True.  When
        /// the CalcLightIntensity() method is called, this value is set to
        /// false.
        mutable bool m_recalcLightValues;

        /// The sine of the azimuth of the light source.
        mutable double m_sinAzimuth;

        /// The sine of the elevation of the light source.
        mutable double m_sinElev;

    };

    /// Renders a normal map from a noise map.
    ///
    /// This class renders an image containing the normal vectors from a noise
    /// map object.  This image can then be used as a bump map for a 3D
    /// application or game.
    ///
    /// This class encodes the (x, y, z) components of the normal vector into
    /// the (red, green, blue) channels of the image.  Like any 24-bit
    /// true-color image, the channel values range from 0 to 255.  0
    /// represents a normal coordinate of -1.0 and 255 represents a normal
    /// coordinate of +1.0.
    ///
    /// You should also specify the <i>bump height</i> before rendering the
    /// normal map.  The bump height specifies the ratio of spatial resolution
    /// to elevation resolution.  For example, if your noise map has a spatial
    /// resolution of 30 meters and an elevation resolution of one meter, set
    /// the bump height to 1.0 / 30.0.
    ///
    /// <b>Rendering the normal map</b>
    ///
    /// To render the image containing the normal map, perform the following
    /// steps:
    /// - Pass a NoiseMap object to the SetSourceNoiseMap() method.
    /// - Pass an Image object to the SetDestImage() method.
    /// - Call the Render() method.
    class RendererNormalMap
    {

      public:

        /// Constructor.
        RendererNormalMap ();

        /// Enables or disables noise-map wrapping.
        ///
        /// @param enable A flag that enables or disables noise-map wrapping.
        ///
        /// This object requires three points (the initial point and the right
        /// and up neighbors) to calculate the normal vector at that point.
        /// If wrapping is/ enabled, and the initial point is on the edge of
        /// the noise map, the appropriate neighbors that lie outside of the
        /// noise map will "wrap" to the opposite side(s) of the noise map.
        /// Otherwise, the appropriate neighbors are cropped to the edge of
        /// the noise map.
        ///
        /// Enabling wrapping is useful when creating spherical and tileable
        /// normal maps.
        void EnableWrap (bool enable = true)
        {
          m_isWrapEnabled = enable;
        }

        /// Returns the bump height.
        ///
        /// @returns The bump height.
        ///
        /// The bump height specifies the ratio of spatial resolution to
        /// elevation resolution.  For example, if your noise map has a
        /// spatial resolution of 30 meters and an elevation resolution of one
        /// meter, set the bump height to 1.0 / 30.0.
        ///
        /// The spatial resolution and elevation resolution are determined by
        /// the application.
        double GetBumpHeight () const
        {
          return m_bumpHeight;
        }

        /// Determines if noise-map wrapping is enabled.
        ///
        /// @returns
        /// - @a true if noise-map wrapping is enabled.
        /// - @a false if noise-map wrapping is disabled.
        ///
        /// This object requires three points (the initial point and the right
        /// and up neighbors) to calculate the normal vector at that point.
        /// If wrapping is/ enabled, and the initial point is on the edge of
        /// the noise map, the appropriate neighbors that lie outside of the
        /// noise map will "wrap" to the opposite side(s) of the noise map.
        /// Otherwise, the appropriate neighbors are cropped to the edge of
        /// the noise map.
        ///
        /// Enabling wrapping is useful when creating spherical and tileable
        /// normal maps.
        bool IsWrapEnabled () const
        {
          return m_isWrapEnabled;
        }

        /// Renders the noise map to the destination image.
        ///
        /// @pre SetSourceNoiseMap() has been previously called.
        /// @pre SetDestImage() has been previously called.
        ///
        /// @post The original contents of the destination image is destroyed.
        ///
        /// @throw noise::ExceptionInvalidParam See the preconditions.
        void Render ();

        /// Sets the bump height.
        ///
        /// @param bumpHeight The bump height.
        ///
        /// The bump height specifies the ratio of spatial resolution to
        /// elevation resolution.  For example, if your noise map has a
        /// spatial resolution of 30 meters and an elevation resolution of one
        /// meter, set the bump height to 1.0 / 30.0.
        ///
        /// The spatial resolution and elevation resolution are determined by
        /// the application.
        void SetBumpHeight (double bumpHeight)
        {
          m_bumpHeight = bumpHeight;
        }

        /// Sets the destination image.
        ///
        /// @param destImage The destination image.
        ///
        /// The destination image will contain the normal map after a
        /// successful call to the Render() method.
        ///
        /// The destination image must exist throughout the lifetime of this
        /// object unless another image replaces that image.
        void SetDestImage (Image& destImage)
        {
          m_pDestImage = &destImage;
        }

        /// Sets the source noise map.
        ///
        /// @param sourceNoiseMap The source noise map.
        ///
        /// The destination image must exist throughout the lifetime of this
        /// object unless another image replaces that image.
        void SetSourceNoiseMap (const NoiseMap& sourceNoiseMap)
        {
          m_pSourceNoiseMap = &sourceNoiseMap;
        }

      private:

        /// Calculates the normal vector at a given point on the noise map.
        ///
        /// @param nc The height of the given point in the noise map.
        /// @param nr The height of the left neighbor.
        /// @param nu The height of the up neighbor.
        /// @param bumpHeight The bump height.
        ///
        /// @returns The normal vector represented as a color.
        ///
        /// This method encodes the (x, y, z) components of the normal vector
        /// into the (red, green, blue) channels of the returned color.  In
        /// order to represent the vector as a color, each coordinate of the
        /// normal is mapped from the -1.0 to 1.0 range to the 0 to 255 range.
        ///
        /// The bump height specifies the ratio of spatial resolution to
        /// elevation resolution.  For example, if your noise map has a
        /// spatial resolution of 30 meters and an elevation resolution of one
        /// meter, set the bump height to 1.0 / 30.0.
        ///
        /// The spatial resolution and elevation resolution are determined by
        /// the application.
        Color CalcNormalColor (double nc, double nr, double nu,
          double bumpHeight) const;

        /// The bump height for the normal map.
        double m_bumpHeight;

        /// A flag specifying whether wrapping is enabled.
        bool m_isWrapEnabled;

        /// A pointer to the destination image.
        Image* m_pDestImage;

        /// A pointer to the source noise map.
        const NoiseMap* m_pSourceNoiseMap;

    };

  }

}

#endif
