diff options
| author | Jon Bergli Heier <snakebite@jvnv.net> | 2011-06-01 19:31:19 +0200 | 
|---|---|---|
| committer | Jon Bergli Heier <snakebite@jvnv.net> | 2011-06-01 19:31:19 +0200 | 
| commit | 6fdbdea4e65b75ac9ebda91320deb656655d3af5 (patch) | |
| tree | 409c8a8da5ccdf8b527ffec9632ec3d6fbb9609e /noiseutils/noiseutils.cpp | |
| parent | 8771dde21514e754a7eb774f7047d17c226d6212 (diff) | |
A bunch of network-related changes.
Diffstat (limited to 'noiseutils/noiseutils.cpp')
| -rw-r--r-- | noiseutils/noiseutils.cpp | 1298 | 
1 files changed, 0 insertions, 1298 deletions
diff --git a/noiseutils/noiseutils.cpp b/noiseutils/noiseutils.cpp deleted file mode 100644 index ddcac1b..0000000 --- a/noiseutils/noiseutils.cpp +++ /dev/null @@ -1,1298 +0,0 @@ -// noiseutils.cpp
 -//
 -// 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'.)
 -//
 -
 -#include <fstream>
 -
 -#include <noise/interp.h>
 -#include <noise/mathconsts.h>
 -
 -#include "noiseutils.h"
 -
 -using namespace noise;
 -using namespace noise::model;
 -using namespace noise::module;
 -
 -// Bitmap header size.
 -const int BMP_HEADER_SIZE = 54;
 -
 -// Direction of the light source, in compass degrees (0 = north, 90 = east,
 -// 180 = south, 270 = east)
 -const double DEFAULT_LIGHT_AZIMUTH = 45.0;
 -
 -// Amount of contrast between light and dark areas.
 -const double DEFAULT_LIGHT_CONTRAST  =  1.0;
 -
 -// Elevation of the light source above the horizon, in degrees (0 = on
 -// horizon, 90 = directly overhead)
 -const double DEFAULT_LIGHT_ELEVATION = 45.0;
 -
 -//////////////////////////////////////////////////////////////////////////////
 -// Miscellaneous functions
 -
 -namespace noise
 -{
 -
 -  namespace utils
 -  {
 -
 -    // Performs linear interpolation between two 8-bit channel values.
 -    inline noise::uint8 BlendChannel (const uint8 channel0,
 -      const uint8 channel1, float alpha)
 -    {
 -      float c0 = (float)channel0 / 255.0;
 -      float c1 = (float)channel1 / 255.0;
 -      return (noise::uint8)(((c1 * alpha) + (c0 * (1.0f - alpha))) * 255.0f);
 -    }
 -
 -    // Performs linear interpolation between two colors and stores the result
 -    // in out.
 -    inline void LinearInterpColor (const Color& color0, const Color& color1,
 -      float alpha, Color& out)
 -    {
 -      out.alpha = BlendChannel (color0.alpha, color1.alpha, alpha);
 -      out.blue  = BlendChannel (color0.blue , color1.blue , alpha);
 -      out.green = BlendChannel (color0.green, color1.green, alpha);
 -      out.red   = BlendChannel (color0.red  , color1.red  , alpha);
 -    }
 -
 -    // Unpacks a floating-point value into four bytes.  This function is
 -    // specific to Intel machines.  A portable version will come soon (I
 -    // hope.)
 -    inline noise::uint8* UnpackFloat (noise::uint8* bytes, float value)
 -    {
 -      noise::uint8* pBytes = (noise::uint8*)(&value);
 -      bytes[0] = *pBytes++;
 -      bytes[1] = *pBytes++;
 -      bytes[2] = *pBytes++;
 -      bytes[3] = *pBytes++;
 -      return bytes;
 -    }
 -
 -    // Unpacks a 16-bit integer value into two bytes in little endian format.
 -    inline noise::uint8* UnpackLittle16 (noise::uint8* bytes,
 -      noise::uint16 integer)
 -    {
 -      bytes[0] = (noise::uint8)((integer & 0x00ff)      );
 -      bytes[1] = (noise::uint8)((integer & 0xff00) >> 8 );
 -      return bytes;
 -    }
 -
 -    // Unpacks a 32-bit integer value into four bytes in little endian format.
 -    inline noise::uint8* UnpackLittle32 (noise::uint8* bytes,
 -      noise::uint32 integer)
 -    {
 -      bytes[0] = (noise::uint8)((integer & 0x000000ff)      );
 -      bytes[1] = (noise::uint8)((integer & 0x0000ff00) >> 8 );
 -      bytes[2] = (noise::uint8)((integer & 0x00ff0000) >> 16);
 -      bytes[3] = (noise::uint8)((integer & 0xff000000) >> 24);
 -      return bytes;
 -    }
 -
 -  }
 -
 -}
 -
 -using namespace noise;
 -
 -using namespace noise::utils;
 -
 -//////////////////////////////////////////////////////////////////////////////
 -// GradientColor class
 -
 -GradientColor::GradientColor ()
 -{
 -  m_pGradientPoints = NULL;
 -}
 -
 -GradientColor::~GradientColor ()
 -{
 -  delete[] m_pGradientPoints;
 -}
 -
 -void GradientColor::AddGradientPoint (double gradientPos,
 -  const Color& gradientColor)
 -{
 -  // Find the insertion point for the new gradient point and insert the new
 -  // gradient point at that insertion point.  The gradient point array will
 -  // remain sorted by gradient position.
 -  int insertionPos = FindInsertionPos (gradientPos);
 -  InsertAtPos (insertionPos, gradientPos, gradientColor);
 -}
 -
 -void GradientColor::Clear ()
 -{
 -  delete[] m_pGradientPoints;
 -  m_pGradientPoints = NULL;
 -  m_gradientPointCount = 0;
 -}
 -
 -int GradientColor::FindInsertionPos (double gradientPos)
 -{
 -  int insertionPos;
 -  for (insertionPos = 0; insertionPos < m_gradientPointCount;
 -    insertionPos++) {
 -    if (gradientPos < m_pGradientPoints[insertionPos].pos) {
 -      // We found the array index in which to insert the new gradient point.
 -      // Exit now.
 -      break;
 -    } else if (gradientPos == m_pGradientPoints[insertionPos].pos) {
 -      // Each gradient point is required to contain a unique gradient
 -      // position, so throw an exception.
 -      throw noise::ExceptionInvalidParam ();
 -    }
 -  }
 -  return insertionPos;
 -}
 -
 -const Color& GradientColor::GetColor (double gradientPos) const
 -{
 -  assert (m_gradientPointCount >= 2);
 -
 -  // Find the first element in the gradient point array that has a gradient
 -  // position larger than the gradient position passed to this method.
 -  int indexPos;
 -  for (indexPos = 0; indexPos < m_gradientPointCount; indexPos++) {
 -    if (gradientPos < m_pGradientPoints[indexPos].pos) {
 -      break;
 -    }
 -  }
 -
 -  // Find the two nearest gradient points so that we can perform linear
 -  // interpolation on the color.
 -  int index0 = ClampValue (indexPos - 1, 0, m_gradientPointCount - 1);
 -  int index1 = ClampValue (indexPos    , 0, m_gradientPointCount - 1);
 -
 -  // If some gradient points are missing (which occurs if the gradient
 -  // position passed to this method is greater than the largest gradient
 -  // position or less than the smallest gradient position in the array), get
 -  // the corresponding gradient color of the nearest gradient point and exit
 -  // now.
 -  if (index0 == index1) {
 -    m_workingColor = m_pGradientPoints[index1].color;
 -    return m_workingColor;
 -  }
 -  
 -  // Compute the alpha value used for linear interpolation.
 -  double input0 = m_pGradientPoints[index0].pos;
 -  double input1 = m_pGradientPoints[index1].pos;
 -  double alpha = (gradientPos - input0) / (input1 - input0);
 -
 -  // Now perform the linear interpolation given the alpha value.
 -  const Color& color0 = m_pGradientPoints[index0].color;
 -  const Color& color1 = m_pGradientPoints[index1].color;
 -  LinearInterpColor (color0, color1, (float)alpha, m_workingColor);
 -  return m_workingColor;
 -}
 -
 -void GradientColor::InsertAtPos (int insertionPos, double gradientPos,
 -  const Color& gradientColor)
 -{
 -  // Make room for the new gradient point at the specified insertion position
 -  // within the gradient point array.  The insertion position is determined by
 -  // the gradient point's position; the gradient points must be sorted by
 -  // gradient position within that array.
 -  GradientPoint* newGradientPoints;
 -  newGradientPoints = new GradientPoint[m_gradientPointCount + 1];
 -  for (int i = 0; i < m_gradientPointCount; i++) {
 -    if (i < insertionPos) {
 -      newGradientPoints[i] = m_pGradientPoints[i];
 -    } else {
 -      newGradientPoints[i + 1] = m_pGradientPoints[i];
 -    }
 -  }
 -  delete[] m_pGradientPoints;
 -  m_pGradientPoints = newGradientPoints;
 -  ++m_gradientPointCount;
 -
 -  // Now that we've made room for the new gradient point within the array, add
 -  // the new gradient point.
 -  m_pGradientPoints[insertionPos].pos = gradientPos ;
 -  m_pGradientPoints[insertionPos].color = gradientColor;
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -// NoiseMap class
 -
 -NoiseMap::NoiseMap ()
 -{
 -  InitObj ();
 -}
 -
 -NoiseMap::NoiseMap (int width, int height)
 -{
 -  InitObj ();
 -  SetSize (width, height);
 -}
 -
 -NoiseMap::NoiseMap (const NoiseMap& rhs)
 -{
 -  InitObj ();
 -  CopyNoiseMap (rhs);
 -}
 -
 -NoiseMap::~NoiseMap ()
 -{
 -  delete[] m_pNoiseMap;
 -}
 -
 -NoiseMap& NoiseMap::operator= (const NoiseMap& rhs)
 -{
 -  CopyNoiseMap (rhs);
 -
 -  return *this;
 -}
 -
 -void NoiseMap::Clear (float value)
 -{
 -  if (m_pNoiseMap != NULL) {
 -    for (int y = 0; y < m_height; y++) {
 -      float* pDest = GetSlabPtr (0, y);
 -      for (int x = 0; x < m_width; x++) {
 -        *pDest++ = value;
 -      }
 -    }
 -  }
 -}
 -
 -void NoiseMap::CopyNoiseMap (const NoiseMap& source)
 -{
 -  // Resize the noise map buffer, then copy the slabs from the source noise
 -  // map buffer to this noise map buffer.
 -  SetSize (source.GetWidth (), source.GetHeight ());
 -  for (int y = 0; y < source.GetHeight (); y++) {
 -    const float* pSource = source.GetConstSlabPtr (0, y);
 -    float* pDest = GetSlabPtr (0, y);
 -    memcpy (pDest, pSource, (size_t)source.GetWidth () * sizeof (float));
 -  }
 -
 -  // Copy the border value as well.
 -  m_borderValue = source.m_borderValue;
 -}
 -
 -void NoiseMap::DeleteNoiseMapAndReset ()
 -{
 -  delete[] m_pNoiseMap;
 -  InitObj ();
 -}
 -
 -float NoiseMap::GetValue (int x, int y) const
 -{
 -  if (m_pNoiseMap != NULL) {
 -    if (x >= 0 && x < m_width && y >= 0 && y < m_height) {
 -      return *(GetConstSlabPtr (x, y));
 -    }
 -  }
 -  // The coordinates specified are outside the noise map.  Return the border
 -  // value.
 -  return m_borderValue;
 -}
 -
 -void NoiseMap::InitObj ()
 -{
 -  m_pNoiseMap = NULL;
 -  m_height    = 0;
 -  m_width     = 0;
 -  m_stride    = 0;
 -  m_memUsed   = 0;
 -  m_borderValue = 0.0;
 -}
 -
 -void NoiseMap::ReclaimMem ()
 -{
 -  size_t newMemUsage = CalcMinMemUsage (m_width, m_height);
 -  if (m_memUsed > newMemUsage) {
 -    // There is wasted memory.  Create the smallest buffer that can fit the
 -    // data and copy the data to it.
 -    float* pNewNoiseMap = NULL;
 -    try {
 -      pNewNoiseMap = new float[newMemUsage];
 -    }
 -    catch (...) {
 -      throw noise::ExceptionOutOfMemory ();
 -    }
 -    memcpy (pNewNoiseMap, m_pNoiseMap, newMemUsage * sizeof (float));
 -    delete[] m_pNoiseMap;
 -    m_pNoiseMap = pNewNoiseMap;
 -    m_memUsed = newMemUsage;
 -  }
 -}
 -
 -void NoiseMap::SetSize (int width, int height)
 -{
 -  if (width < 0 || height < 0
 -    || width > RASTER_MAX_WIDTH || height > RASTER_MAX_HEIGHT) {
 -    // Invalid width or height.
 -    throw noise::ExceptionInvalidParam ();
 -  } else if (width == 0 || height == 0) {
 -    // An empty noise map was specified.  Delete it and zero out the size
 -    // member variables.
 -    DeleteNoiseMapAndReset ();
 -  } else {
 -    // A new noise map size was specified.  Allocate a new noise map buffer
 -    // unless the current buffer is large enough for the new noise map (we
 -    // don't want costly reallocations going on.)
 -    size_t newMemUsage = CalcMinMemUsage (width, height);
 -    if (m_memUsed < newMemUsage) {
 -      // The new size is too big for the current noise map buffer.  We need to
 -      // reallocate.
 -      DeleteNoiseMapAndReset ();
 -      try {
 -        m_pNoiseMap = new float[newMemUsage];
 -      }
 -      catch (...) {
 -        throw noise::ExceptionOutOfMemory ();
 -      }
 -      m_memUsed = newMemUsage;
 -    }
 -    m_stride = (int)CalcStride (width);
 -    m_width  = width;
 -    m_height = height;
 -  }
 -}
 -
 -void NoiseMap::SetValue (int x, int y, float value)
 -{
 -  if (m_pNoiseMap != NULL) {
 -    if (x >= 0 && x < m_width && y >= 0 && y < m_height) {
 -      *(GetSlabPtr (x, y)) = value;
 -    }
 -  }
 -}
 -
 -void NoiseMap::TakeOwnership (NoiseMap& source)
 -{
 -  // Copy the values and the noise map buffer from the source noise map to
 -  // this noise map.  Now this noise map pwnz the source buffer.
 -  delete[] m_pNoiseMap;
 -  m_memUsed   = source.m_memUsed;
 -  m_height    = source.m_height;
 -  m_pNoiseMap = source.m_pNoiseMap;
 -  m_stride    = source.m_stride;
 -  m_width     = source.m_width;
 -
 -  // Now that the source buffer is assigned to this noise map, reset the
 -  // source noise map object.
 -  source.InitObj ();
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -// Image class
 -
 -Image::Image ()
 -{
 -  InitObj ();
 -}
 -
 -Image::Image (int width, int height)
 -{
 -  InitObj ();
 -  SetSize (width, height);
 -}
 -
 -Image::Image (const Image& rhs)
 -{
 -  InitObj ();
 -  CopyImage (rhs);
 -}
 -
 -Image::~Image ()
 -{
 -  delete[] m_pImage;
 -}
 -
 -Image& Image::operator= (const Image& rhs)
 -{
 -  CopyImage (rhs);
 -
 -  return *this;
 -}
 -
 -void Image::Clear (const Color& value)
 -{
 -  if (m_pImage != NULL) {
 -    for (int y = 0; y < m_height; y++) {
 -      Color* pDest = GetSlabPtr (0, y);
 -      for (int x = 0; x < m_width; x++) {
 -        *pDest++ = value;
 -      }
 -    }
 -  }
 -}
 -
 -void Image::CopyImage (const Image& source)
 -{
 -  // Resize the image buffer, then copy the slabs from the source image
 -  // buffer to this image buffer.
 -  SetSize (source.GetWidth (), source.GetHeight ());
 -  for (int y = 0; y < source.GetHeight (); y++) {
 -    const Color* pSource = source.GetConstSlabPtr (0, y);
 -    Color* pDest = GetSlabPtr (0, y);
 -    memcpy (pDest, pSource, (size_t)source.GetWidth () * sizeof (float));
 -  }
 -
 -  // Copy the border value as well.
 -  m_borderValue = source.m_borderValue;
 -}
 -
 -void Image::DeleteImageAndReset ()
 -{
 -  delete[] m_pImage;
 -  InitObj ();
 -}
 -
 -Color Image::GetValue (int x, int y) const
 -{
 -  if (m_pImage != NULL) {
 -    if (x >= 0 && x < m_width && y >= 0 && y < m_height) {
 -      return *(GetConstSlabPtr (x, y));
 -    }
 -  }
 -  // The coordinates specified are outside the image.  Return the border
 -  // value.
 -  return m_borderValue;
 -}
 -
 -void Image::InitObj ()
 -{
 -  m_pImage  = NULL;
 -  m_height  = 0;
 -  m_width   = 0;
 -  m_stride  = 0;
 -  m_memUsed = 0;
 -  m_borderValue = Color (0, 0, 0, 0);
 -}
 -
 -void Image::ReclaimMem ()
 -{
 -  size_t newMemUsage = CalcMinMemUsage (m_width, m_height);
 -  if (m_memUsed > newMemUsage) {
 -    // There is wasted memory.  Create the smallest buffer that can fit the
 -    // data and copy the data to it.
 -    Color* pNewImage = NULL;
 -    try {
 -      pNewImage = new Color[newMemUsage];
 -    }
 -    catch (...) {
 -      throw noise::ExceptionOutOfMemory ();
 -    }
 -    memcpy (pNewImage, m_pImage, newMemUsage * sizeof (float));
 -    delete[] m_pImage;
 -    m_pImage = pNewImage;
 -    m_memUsed = newMemUsage;
 -  }
 -}
 -
 -void Image::SetSize (int width, int height)
 -{
 -  if (width < 0 || height < 0
 -    || width > RASTER_MAX_WIDTH || height > RASTER_MAX_HEIGHT) {
 -    // Invalid width or height.
 -    throw noise::ExceptionInvalidParam ();
 -  } else if (width == 0 || height == 0) {
 -    // An empty image was specified.  Delete it and zero out the size member
 -    // variables.
 -    DeleteImageAndReset ();
 -  } else {
 -    // A new image size was specified.  Allocate a new image buffer unless
 -    // the current buffer is large enough for the new image (we don't want
 -    // costly reallocations going on.)
 -    size_t newMemUsage = CalcMinMemUsage (width, height);
 -    if (m_memUsed < newMemUsage) {
 -      // The new size is too big for the current image buffer.  We need to
 -      // reallocate.
 -      DeleteImageAndReset ();
 -      try {
 -        m_pImage = new Color[newMemUsage];
 -      }
 -      catch (...) {
 -        throw noise::ExceptionOutOfMemory ();
 -      }
 -      m_memUsed = newMemUsage;
 -    }
 -    m_stride = (int)CalcStride (width);
 -    m_width  = width;
 -    m_height = height;
 -  }
 -}
 -
 -void Image::SetValue (int x, int y, const Color& value)
 -{
 -  if (m_pImage != NULL) {
 -    if (x >= 0 && x < m_width && y >= 0 && y < m_height) {
 -      *(GetSlabPtr (x, y)) = value;
 -    }
 -  }
 -}
 -
 -void Image::TakeOwnership (Image& source)
 -{
 -  // Copy the values and the image buffer from the source image to this image.
 -  // Now this image pwnz the source buffer.
 -  delete[] m_pImage;
 -  m_memUsed = source.m_memUsed;
 -  m_height  = source.m_height;
 -  m_pImage  = source.m_pImage;
 -  m_stride  = source.m_stride;
 -  m_width   = source.m_width;
 -
 -  // Now that the source buffer is assigned to this image, reset the source
 -  // image object.
 -  source.InitObj ();
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////
 -// WriterBMP class
 -
 -int WriterBMP::CalcWidthByteCount (int width) const
 -{
 -  return ((width * 3) + 3) & ~0x03;
 -}
 -
 -void WriterBMP::WriteDestFile ()
 -{
 -  if (m_pSourceImage == NULL) {
 -    throw noise::ExceptionInvalidParam ();
 -  }
 -
 -  int width  = m_pSourceImage->GetWidth  ();
 -  int height = m_pSourceImage->GetHeight ();
 -
 -  // The width of one line in the file must be aligned on a 4-byte boundary.
 -  int bufferSize = CalcWidthByteCount (width);
 -  int destSize   = bufferSize * height;
 -
 -  // This buffer holds one horizontal line in the destination file.
 -  noise::uint8* pLineBuffer = NULL;
 -
 -  // File object used to write the file.
 -  std::ofstream os;
 -  os.clear ();
 -  
 -  // Allocate a buffer to hold one horizontal line in the bitmap.
 -  try {
 -    pLineBuffer = new noise::uint8[bufferSize];
 -  }
 -  catch (...) {
 -    throw noise::ExceptionOutOfMemory ();
 -  }
 -
 -  // Open the destination file.
 -  os.open (m_destFilename.c_str (), std::ios::out | std::ios::binary);
 -  if (os.fail () || os.bad ()) {
 -    delete[] pLineBuffer;
 -    throw noise::ExceptionUnknown ();
 -  }
 -
 -  // Build the header.
 -  noise::uint8 d[4];
 -  os.write ("BM", 2);
 -  os.write ((char*)UnpackLittle32 (d, destSize + BMP_HEADER_SIZE), 4);
 -  os.write ("\0\0\0\0", 4);
 -  os.write ((char*)UnpackLittle32 (d, (noise::uint32)BMP_HEADER_SIZE), 4);
 -  os.write ((char*)UnpackLittle32 (d, 40), 4);   // Palette offset
 -  os.write ((char*)UnpackLittle32 (d, (noise::uint32)width ), 4);
 -  os.write ((char*)UnpackLittle32 (d, (noise::uint32)height), 4);
 -  os.write ((char*)UnpackLittle16 (d, 1 ), 2);   // Planes per pixel
 -  os.write ((char*)UnpackLittle16 (d, 24), 2);   // Bits per plane
 -  os.write ("\0\0\0\0", 4); // Compression (0 = none)
 -  os.write ((char*)UnpackLittle32 (d, (noise::uint32)destSize), 4);
 -  os.write ((char*)UnpackLittle32 (d, 2834), 4); // X pixels per meter
 -  os.write ((char*)UnpackLittle32 (d, 2834), 4); // Y pixels per meter
 -  os.write ("\0\0\0\0", 4);
 -  os.write ("\0\0\0\0", 4);
 -  if (os.fail () || os.bad ()) {
 -    os.clear ();
 -    os.close ();
 -    os.clear ();
 -    delete[] pLineBuffer;
 -    throw noise::ExceptionUnknown ();
 -  }
 -
 -  // Build and write each horizontal line to the file.
 -  for (int y = 0; y < height; y++) {
 -    memset (pLineBuffer, 0, bufferSize);
 -    Color* pSource = m_pSourceImage->GetSlabPtr (y);
 -    noise::uint8* pDest   = pLineBuffer;
 -    for (int x = 0; x < width; x++) {
 -      *pDest++ = pSource->blue ;
 -      *pDest++ = pSource->green;
 -      *pDest++ = pSource->red  ;
 -      ++pSource;
 -    }
 -    os.write ((char*)pLineBuffer, (size_t)bufferSize);
 -    if (os.fail () || os.bad ()) {
 -      os.clear ();
 -      os.close ();
 -      os.clear ();
 -      delete[] pLineBuffer;
 -      throw noise::ExceptionUnknown ();
 -    }
 -  }
 -
 -  os.close ();
 -  os.clear ();
 -  delete[] pLineBuffer;
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////
 -// WriterTER class
 -
 -int WriterTER::CalcWidthByteCount (int width) const
 -{
 -  return (width * sizeof (int16));
 -}
 -
 -void WriterTER::WriteDestFile ()
 -{
 -  if (m_pSourceNoiseMap == NULL) {
 -    throw noise::ExceptionInvalidParam ();
 -  }
 -
 -  int width  = m_pSourceNoiseMap->GetWidth  ();
 -  int height = m_pSourceNoiseMap->GetHeight ();
 -
 -  int bufferSize = CalcWidthByteCount (width);
 -
 -  // This buffer holds one horizontal line in the destination file.
 -  noise::uint8* pLineBuffer = NULL;
 -
 -  // File object used to write the file.
 -  std::ofstream os;
 -  os.clear ();
 -
 -  // Allocate a buffer to hold one horizontal line in the height map.
 -  try {
 -    pLineBuffer = new noise::uint8[bufferSize];
 -  }
 -  catch (...) {
 -    throw noise::ExceptionOutOfMemory ();
 -  }
 -
 -  // Open the destination file.
 -  os.open (m_destFilename.c_str (), std::ios::out | std::ios::binary);
 -  if (os.fail () || os.bad ()) {
 -    os.clear ();
 -    delete[] pLineBuffer;
 -    throw noise::ExceptionUnknown ();
 -  }
 -
 -  // Build the header.
 -  noise::uint8 d[4];
 -  int16 heightScale = (int16)(floor (32768.0 / (double)m_metersPerPoint));
 -  os.write ("TERRAGENTERRAIN ", 16);
 -  os.write ("SIZE", 4);
 -  os.write ((char*)UnpackLittle16 (d, GetMin (width, height) - 1), 2);
 -  os.write ("\0\0", 2);
 -  os.write ("XPTS", 4);
 -  os.write ((char*)UnpackLittle16 (d, width), 2);
 -  os.write ("\0\0", 2);
 -  os.write ("YPTS", 4);
 -  os.write ((char*)UnpackLittle16 (d, height), 2);
 -  os.write ("\0\0", 2);
 -  os.write ("SCAL", 4);
 -  os.write ((char*)UnpackFloat (d, m_metersPerPoint), 4);
 -  os.write ((char*)UnpackFloat (d, m_metersPerPoint), 4);
 -  os.write ((char*)UnpackFloat (d, m_metersPerPoint), 4);
 -  os.write ("ALTW", 4);
 -  os.write ((char*)UnpackLittle16 (d, heightScale), 2);
 -  os.write ("\0\0", 2);
 -  if (os.fail () || os.bad ()) {
 -    os.clear ();
 -    os.close ();
 -    os.clear ();
 -    delete[] pLineBuffer;
 -    throw noise::ExceptionUnknown ();
 -  }
 -
 -  // Build and write each horizontal line to the file.
 -  for (int y = 0; y < height; y++) {
 -    float* pSource = m_pSourceNoiseMap->GetSlabPtr (y);
 -    noise::uint8* pDest   = pLineBuffer;
 -    for (int x = 0; x < width; x++) {
 -      int16 scaledHeight = (int16)(floor (*pSource * 2.0));
 -      UnpackLittle16 (pDest, scaledHeight);
 -      pDest += 2;
 -      ++pSource;
 -    }
 -    os.write ((char*)pLineBuffer, (size_t)bufferSize);
 -    if (os.fail () || os.bad ()) {
 -      os.clear ();
 -      os.close ();
 -      os.clear ();
 -      delete[] pLineBuffer;
 -      throw noise::ExceptionUnknown ();
 -    }
 -  }
 -
 -  os.close ();
 -  os.clear ();
 -  delete[] pLineBuffer;
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////
 -// NoiseMapBuilder class
 -
 -NoiseMapBuilder::NoiseMapBuilder ():
 -  m_pCallback (NULL),
 -  m_destHeight (0),
 -  m_destWidth  (0),
 -  m_pDestNoiseMap (NULL),
 -  m_pSourceModule (NULL)
 -{
 -}
 -
 -void NoiseMapBuilder::SetCallback (NoiseMapCallback pCallback)
 -{
 -  m_pCallback = pCallback;
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////
 -// NoiseMapBuilderCylinder class
 -
 -NoiseMapBuilderCylinder::NoiseMapBuilderCylinder ():
 -  m_lowerAngleBound  (0.0),
 -  m_lowerHeightBound (0.0),
 -  m_upperAngleBound  (0.0),
 -  m_upperHeightBound (0.0)
 -{
 -}
 -
 -void NoiseMapBuilderCylinder::Build ()
 -{
 -  if ( m_upperAngleBound <= m_lowerAngleBound
 -    || m_upperHeightBound <= m_lowerHeightBound
 -    || m_destWidth <= 0
 -    || m_destHeight <= 0
 -    || m_pSourceModule == NULL
 -    || m_pDestNoiseMap == NULL) {
 -    throw noise::ExceptionInvalidParam ();
 -  }
 -
 -  // Resize the destination noise map so that it can store the new output
 -  // values from the source model.
 -  m_pDestNoiseMap->SetSize (m_destWidth, m_destHeight);
 -
 -  // Create the cylinder model.
 -  model::Cylinder cylinderModel;
 -  cylinderModel.SetModule (*m_pSourceModule);
 -
 -  double angleExtent  = m_upperAngleBound  - m_lowerAngleBound ;
 -  double heightExtent = m_upperHeightBound - m_lowerHeightBound;
 -  double xDelta = angleExtent  / (double)m_destWidth ;
 -  double yDelta = heightExtent / (double)m_destHeight;
 -  double curAngle  = m_lowerAngleBound ;
 -  double curHeight = m_lowerHeightBound;
 -
 -  // Fill every point in the noise map with the output values from the model.
 -  for (int y = 0; y < m_destHeight; y++) {
 -    float* pDest = m_pDestNoiseMap->GetSlabPtr (y);
 -    curAngle = m_lowerAngleBound;
 -    for (int x = 0; x < m_destWidth; x++) {
 -      float curValue = (float)cylinderModel.GetValue (curAngle, curHeight);
 -      *pDest++ = curValue;
 -      curAngle += xDelta;
 -    }
 -    curHeight += yDelta;
 -    if (m_pCallback != NULL) {
 -      m_pCallback (y);
 -    }
 -  }
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////
 -// NoiseMapBuilderPlane class
 -
 -NoiseMapBuilderPlane::NoiseMapBuilderPlane ():
 -  m_isSeamlessEnabled (false),
 -  m_lowerXBound  (0.0),
 -  m_lowerZBound  (0.0),
 -  m_upperXBound  (0.0),
 -  m_upperZBound  (0.0)
 -{
 -}
 -
 -void NoiseMapBuilderPlane::Build ()
 -{
 -  if ( m_upperXBound <= m_lowerXBound
 -    || m_upperZBound <= m_lowerZBound
 -    || m_destWidth <= 0
 -    || m_destHeight <= 0
 -    || m_pSourceModule == NULL
 -    || m_pDestNoiseMap == NULL) {
 -    throw noise::ExceptionInvalidParam ();
 -  }
 -
 -  // Resize the destination noise map so that it can store the new output
 -  // values from the source model.
 -  m_pDestNoiseMap->SetSize (m_destWidth, m_destHeight);
 -
 -  // Create the plane model.
 -  model::Plane planeModel;
 -  planeModel.SetModule (*m_pSourceModule);
 -
 -  double xExtent = m_upperXBound - m_lowerXBound;
 -  double zExtent = m_upperZBound - m_lowerZBound;
 -  double xDelta  = xExtent / (double)m_destWidth ;
 -  double zDelta  = zExtent / (double)m_destHeight;
 -  double xCur    = m_lowerXBound;
 -  double zCur    = m_lowerZBound;
 -
 -  // Fill every point in the noise map with the output values from the model.
 -  for (int z = 0; z < m_destHeight; z++) {
 -    float* pDest = m_pDestNoiseMap->GetSlabPtr (z);
 -    xCur = m_lowerXBound;
 -    for (int x = 0; x < m_destWidth; x++) {
 -      float finalValue;
 -      if (!m_isSeamlessEnabled) {
 -        finalValue = planeModel.GetValue (xCur, zCur);
 -      } else {
 -        double swValue, seValue, nwValue, neValue;
 -        swValue = planeModel.GetValue (xCur          , zCur          );
 -        seValue = planeModel.GetValue (xCur + xExtent, zCur          );
 -        nwValue = planeModel.GetValue (xCur          , zCur + zExtent);
 -        neValue = planeModel.GetValue (xCur + xExtent, zCur + zExtent);
 -        double xBlend = 1.0 - ((xCur - m_lowerXBound) / xExtent);
 -        double zBlend = 1.0 - ((zCur - m_lowerZBound) / zExtent);
 -        double z0 = LinearInterp (swValue, seValue, xBlend);
 -        double z1 = LinearInterp (nwValue, neValue, xBlend);
 -        finalValue = (float)LinearInterp (z0, z1, zBlend);
 -      }
 -      *pDest++ = finalValue;
 -      xCur += xDelta;
 -    }
 -    zCur += zDelta;
 -    if (m_pCallback != NULL) {
 -      m_pCallback (z);
 -    }
 -  }
 -}
 -
 -/////////////////////////////////////////////////////////////////////////////
 -// NoiseMapBuilderSphere class
 -
 -NoiseMapBuilderSphere::NoiseMapBuilderSphere ():
 -  m_eastLonBound  (0.0),
 -  m_northLatBound (0.0),
 -  m_southLatBound (0.0),
 -  m_westLonBound  (0.0)
 -{
 -}
 -
 -void NoiseMapBuilderSphere::Build ()
 -{
 -  if ( m_eastLonBound <= m_westLonBound
 -    || m_northLatBound <= m_southLatBound
 -    || m_destWidth <= 0
 -    || m_destHeight <= 0
 -    || m_pSourceModule == NULL
 -    || m_pDestNoiseMap == NULL) {
 -    throw noise::ExceptionInvalidParam ();
 -  }
 -
 -  // Resize the destination noise map so that it can store the new output
 -  // values from the source model.
 -  m_pDestNoiseMap->SetSize (m_destWidth, m_destHeight);
 -
 -  // Create the plane model.
 -  model::Sphere sphereModel;
 -  sphereModel.SetModule (*m_pSourceModule);
 -
 -  double lonExtent = m_eastLonBound  - m_westLonBound ;
 -  double latExtent = m_northLatBound - m_southLatBound;
 -  double xDelta = lonExtent / (double)m_destWidth ;
 -  double yDelta = latExtent / (double)m_destHeight;
 -  double curLon = m_westLonBound ;
 -  double curLat = m_southLatBound;
 -
 -  // Fill every point in the noise map with the output values from the model.
 -  for (int y = 0; y < m_destHeight; y++) {
 -    float* pDest = m_pDestNoiseMap->GetSlabPtr (y);
 -    curLon = m_westLonBound;
 -    for (int x = 0; x < m_destWidth; x++) {
 -      float curValue = (float)sphereModel.GetValue (curLat, curLon);
 -      *pDest++ = curValue;
 -      curLon += xDelta;
 -    }
 -    curLat += yDelta;
 -    if (m_pCallback != NULL) {
 -      m_pCallback (y);
 -    }
 -  }
 -}
 -
 -//////////////////////////////////////////////////////////////////////////////
 -// RendererImage class
 -
 -RendererImage::RendererImage ():
 -  m_isLightEnabled    (false),
 -  m_isWrapEnabled     (false),
 -  m_lightAzimuth      (45.0),
 -  m_lightBrightness   (1.0),
 -  m_lightColor        (255, 255, 255, 255),
 -  m_lightContrast     (1.0),
 -  m_lightElev         (45.0),
 -  m_lightIntensity    (1.0),
 -  m_pBackgroundImage  (NULL),
 -  m_pDestImage        (NULL),
 -  m_pSourceNoiseMap   (NULL),
 -  m_recalcLightValues (true)
 -{
 -  BuildGrayscaleGradient ();
 -};
 -
 -void RendererImage::AddGradientPoint (double gradientPos,
 -  const Color& gradientColor)
 -{
 -  m_gradient.AddGradientPoint (gradientPos, gradientColor);
 -}
 -
 -void RendererImage::BuildGrayscaleGradient ()
 -{
 -  ClearGradient ();
 -  m_gradient.AddGradientPoint (-1.0, Color (  0,   0,   0, 255));
 -  m_gradient.AddGradientPoint ( 1.0, Color (255, 255, 255, 255));
 -}
 -
 -void RendererImage::BuildTerrainGradient ()
 -{
 -  ClearGradient ();
 -  m_gradient.AddGradientPoint (-1.00, Color (  0,   0, 128, 255));
 -  m_gradient.AddGradientPoint (-0.20, Color ( 32,  64, 128, 255));
 -  m_gradient.AddGradientPoint (-0.04, Color ( 64,  96, 192, 255));
 -  m_gradient.AddGradientPoint (-0.02, Color (192, 192, 128, 255));
 -  m_gradient.AddGradientPoint ( 0.00, Color (  0, 192,   0, 255));
 -  m_gradient.AddGradientPoint ( 0.25, Color (192, 192,   0, 255));
 -  m_gradient.AddGradientPoint ( 0.50, Color (160,  96,  64, 255));
 -  m_gradient.AddGradientPoint ( 0.75, Color (128, 255, 255, 255));
 -  m_gradient.AddGradientPoint ( 1.00, Color (255, 255, 255, 255));
 -}
 -
 -Color RendererImage::CalcDestColor (const Color& sourceColor,
 -  const Color& backgroundColor, double lightValue) const
 -{
 -  double sourceRed   = (double)sourceColor.red   / 255.0;
 -  double sourceGreen = (double)sourceColor.green / 255.0;
 -  double sourceBlue  = (double)sourceColor.blue  / 255.0;
 -  double sourceAlpha = (double)sourceColor.alpha / 255.0;
 -  double backgroundRed   = (double)backgroundColor.red   / 255.0;
 -  double backgroundGreen = (double)backgroundColor.green / 255.0;
 -  double backgroundBlue  = (double)backgroundColor.blue  / 255.0;
 -
 -  // First, blend the source color to the background color using the alpha
 -  // of the source color.
 -  double red   = LinearInterp (backgroundRed,   sourceRed  , sourceAlpha);
 -  double green = LinearInterp (backgroundGreen, sourceGreen, sourceAlpha);
 -  double blue  = LinearInterp (backgroundBlue,  sourceBlue , sourceAlpha);
 -
 -  if (m_isLightEnabled) {
 -
 -    // Now calculate the light color.
 -    double lightRed   = lightValue * (double)m_lightColor.red   / 255.0;
 -    double lightGreen = lightValue * (double)m_lightColor.green / 255.0;
 -    double lightBlue  = lightValue * (double)m_lightColor.blue  / 255.0;
 -
 -    // Apply the light color to the new color.
 -    red   *= lightRed  ;
 -    green *= lightGreen;
 -    blue  *= lightBlue ;
 -  }
 -
 -  // Clamp the color channels to the (0..1) range.
 -  red   = (red   < 0.0)? 0.0: red  ;
 -  red   = (red   > 1.0)? 1.0: red  ;
 -  green = (green < 0.0)? 0.0: green;
 -  green = (green > 1.0)? 1.0: green;
 -  blue  = (blue  < 0.0)? 0.0: blue ;
 -  blue  = (blue  > 1.0)? 1.0: blue ;
 -
 -  // Rescale the color channels to the noise::uint8 (0..255) range and return
 -  // the new color.
 -  Color newColor (
 -    (noise::uint8)((noise::uint)(red   * 255.0) & 0xff),
 -    (noise::uint8)((noise::uint)(green * 255.0) & 0xff),
 -    (noise::uint8)((noise::uint)(blue  * 255.0) & 0xff),
 -    GetMax (sourceColor.alpha, backgroundColor.alpha));
 -  return newColor;
 -}
 -
 -double RendererImage::CalcLightIntensity (double center, double left,
 -  double right, double down, double up) const
 -{
 -  // Recalculate the sine and cosine of the various light values if
 -  // necessary so it does not have to be calculated each time this method is
 -  // called.
 -  if (m_recalcLightValues) {
 -    m_cosAzimuth = cos (m_lightAzimuth * DEG_TO_RAD);
 -    m_sinAzimuth = sin (m_lightAzimuth * DEG_TO_RAD);
 -    m_cosElev    = cos (m_lightElev    * DEG_TO_RAD);
 -    m_sinElev    = sin (m_lightElev    * DEG_TO_RAD);
 -    m_recalcLightValues = false;
 -  }
 -
 -  // Now do the lighting calculations.
 -  const double I_MAX = 1.0;
 -  double io = I_MAX * SQRT_2 * m_sinElev / 2.0;
 -  double ix = (I_MAX - io) * m_lightContrast * SQRT_2 * m_cosElev
 -    * m_cosAzimuth;
 -  double iy = (I_MAX - io) * m_lightContrast * SQRT_2 * m_cosElev
 -    * m_sinAzimuth; 
 -  double intensity = (ix * (left - right) + iy * (down - up) + io);
 -  if (intensity < 0.0) {
 -    intensity = 0.0;
 -  }
 -  return intensity;
 -}
 -
 -void RendererImage::ClearGradient ()
 -{
 -  m_gradient.Clear ();
 -}
 -
 -void RendererImage::Render ()
 -{
 -  if ( m_pSourceNoiseMap == NULL
 -    || m_pDestImage == NULL
 -    || m_pSourceNoiseMap->GetWidth  () <= 0
 -    || m_pSourceNoiseMap->GetHeight () <= 0
 -    || m_gradient.GetGradientPointCount () < 2) {
 -    throw noise::ExceptionInvalidParam ();
 -  }
 -
 -  int width  = m_pSourceNoiseMap->GetWidth  ();
 -  int height = m_pSourceNoiseMap->GetHeight ();
 -
 -  // If a background image was provided, make sure it is the same size the
 -  // source noise map.
 -  if (m_pBackgroundImage != NULL) {
 -    if ( m_pBackgroundImage->GetWidth  () != width
 -      || m_pBackgroundImage->GetHeight () !=   | 
