From 7d5a21ddbf738c51197a98bef11a52ceb85fe907 Mon Sep 17 00:00:00 2001 From: Justin Clarke Casey Date: Sun, 29 Jun 2008 19:21:43 +0000 Subject: [PATCH] * Allow terrains to be loaded and saved from streams as well as directly to and from files * Should be making use of this in the next revisions --- .../Modules/World/Terrain/FileLoaders/BMP.cs | 14 +++++ .../Modules/World/Terrain/FileLoaders/GIF.cs | 14 +++++ .../FileLoaders/GenericSystemDrawing.cs | 51 +++++++++++----- .../Modules/World/Terrain/FileLoaders/JPEG.cs | 18 ++++++ .../World/Terrain/FileLoaders/LLRAW.cs | 41 ++++++++----- .../Modules/World/Terrain/FileLoaders/PNG.cs | 14 +++++ .../World/Terrain/FileLoaders/RAW32.cs | 44 ++++++++----- .../Modules/World/Terrain/FileLoaders/TIFF.cs | 14 +++++ .../World/Terrain/FileLoaders/Terragen.cs | 21 +++++-- .../Modules/World/Terrain/ITerrainLoader.cs | 3 + .../Modules/World/Terrain/ITerrainModule.cs | 21 +++++++ .../Modules/World/Terrain/TerrainModule.cs | 61 +++++++++++++++++++ 12 files changed, 268 insertions(+), 48 deletions(-) diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/BMP.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/BMP.cs index 98d69a52c9..34bbf781a3 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/BMP.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/BMP.cs @@ -24,8 +24,10 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System.Drawing; using System.Drawing.Imaging; +using System.IO; using OpenSim.Region.Environment.Interfaces; namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders @@ -49,6 +51,18 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders colours.Save(filename, ImageFormat.Bmp); } + + /// + /// Exports a stream using a System.Drawing exporter. + /// + /// The target stream + /// The terrain channel being saved + public override void SaveStream(Stream stream, ITerrainChannel map) + { + Bitmap colours = CreateGrayscaleBitmapFromMap(map); + + colours.Save(stream, ImageFormat.Png); + } /// /// The human readable version of the file format(s) this loader handles diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GIF.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GIF.cs index 9bfe851f1a..0cd9000253 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GIF.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GIF.cs @@ -24,8 +24,10 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System.Drawing; using System.Drawing.Imaging; +using System.IO; using OpenSim.Region.Environment.Interfaces; namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders @@ -38,6 +40,18 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders colours.Save(filename, ImageFormat.Gif); } + + /// + /// Exports a stream using a System.Drawing exporter. + /// + /// The target stream + /// The terrain channel being saved + public override void SaveStream(Stream stream, ITerrainChannel map) + { + Bitmap colours = CreateGrayscaleBitmapFromMap(map); + + colours.Save(stream, ImageFormat.Gif); + } public override string ToString() { diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GenericSystemDrawing.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GenericSystemDrawing.cs index f87d3ee60f..4d213e0883 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GenericSystemDrawing.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/GenericSystemDrawing.cs @@ -28,6 +28,7 @@ using System; using System.Drawing; using System.Drawing.Imaging; +using System.IO; using OpenSim.Region.Environment.Interfaces; namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders @@ -57,27 +58,35 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders /// A terrain channel generated from the image. public virtual ITerrainChannel LoadFile(string filename) { - Bitmap file = new Bitmap(filename); - - ITerrainChannel retval = new TerrainChannel(file.Width, file.Height); - - int x; - for (x = 0; x < file.Width; x++) - { - int y; - for (y = 0; y < file.Height; y++) - { - retval[x, y] = file.GetPixel(x, file.Height - y - 1).GetBrightness() * 128; - } - } - - return retval; + return LoadBitmap(new Bitmap(filename)); } public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) { throw new NotImplementedException(); } + + public virtual ITerrainChannel LoadStream(Stream stream) + { + return LoadBitmap(new Bitmap(stream)); + } + + protected virtual ITerrainChannel LoadBitmap(Bitmap bitmap) + { + ITerrainChannel retval = new TerrainChannel(bitmap.Width, bitmap.Height); + + int x; + for (x = 0; x < bitmap.Width; x++) + { + int y; + for (y = 0; y < bitmap.Height; y++) + { + retval[x, y] = bitmap.GetPixel(x, bitmap.Height - y - 1).GetBrightness() * 128; + } + } + + return retval; + } /// /// Exports a file to a image on the disk using a System.Drawing exporter. @@ -90,6 +99,18 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders colours.Save(filename, ImageFormat.Png); } + + /// + /// Exports a stream using a System.Drawing exporter. + /// + /// The target stream + /// The terrain channel being saved + public virtual void SaveStream(Stream stream, ITerrainChannel map) + { + Bitmap colours = CreateGrayscaleBitmapFromMap(map); + + colours.Save(stream, ImageFormat.Png); + } #endregion diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/JPEG.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/JPEG.cs index 628c20197a..9886b81a63 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/JPEG.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/JPEG.cs @@ -28,6 +28,7 @@ using System; using System.Drawing; using System.Drawing.Imaging; +using System.IO; using OpenSim.Region.Environment.Interfaces; namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders @@ -50,6 +51,11 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders { throw new NotImplementedException(); } + + public ITerrainChannel LoadStream(Stream stream) + { + throw new NotImplementedException(); + } public void SaveFile(string filename, ITerrainChannel map) { @@ -57,6 +63,18 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders colours.Save(filename, ImageFormat.Jpeg); } + + /// + /// Exports a stream using a System.Drawing exporter. + /// + /// The target stream + /// The terrain channel being saved + public void SaveStream(Stream stream, ITerrainChannel map) + { + Bitmap colours = CreateBitmapFromMap(map); + + colours.Save(stream, ImageFormat.Jpeg); + } #endregion diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/LLRAW.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/LLRAW.cs index 85afaf8e34..d8d064848f 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/LLRAW.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/LLRAW.cs @@ -71,10 +71,24 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders public ITerrainChannel LoadFile(string filename) { - TerrainChannel retval = new TerrainChannel(); - FileInfo file = new FileInfo(filename); FileStream s = file.Open(FileMode.Open, FileAccess.Read); + ITerrainChannel retval = LoadStream(s); + + s.Close(); + + return retval; + } + + public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) + { + throw new NotImplementedException(); + } + + public ITerrainChannel LoadStream(Stream s) + { + TerrainChannel retval = new TerrainChannel(); + BinaryReader bs = new BinaryReader(s); int y; for (y = 0; y < retval.Height; y++) @@ -87,21 +101,22 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders } } - bs.Close(); - s.Close(); - + bs.Close(); + return retval; } - public ITerrainChannel LoadFile(string filename, int x, int y, int fileWidth, int fileHeight, int w, int h) - { - throw new NotImplementedException(); - } - public void SaveFile(string filename, ITerrainChannel map) { FileInfo file = new FileInfo(filename); FileStream s = file.Open(FileMode.CreateNew, FileAccess.Write); + SaveStream(s, map); + + s.Close(); + } + + public void SaveStream(Stream s, ITerrainChannel map) + { BinaryWriter binStream = new BinaryWriter(s); // Output the calculated raw @@ -150,11 +165,9 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders } } - binStream.Close(); - s.Close(); + binStream.Close(); } - - + public string FileExtension { get { return ".raw"; } diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/PNG.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/PNG.cs index b893f70f69..cf954869ae 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/PNG.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/PNG.cs @@ -24,8 +24,10 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System.Drawing; using System.Drawing.Imaging; +using System.IO; using OpenSim.Region.Environment.Interfaces; namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders @@ -38,6 +40,18 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders colours.Save(filename, ImageFormat.Png); } + + /// + /// Exports a stream using a System.Drawing exporter. + /// + /// The target stream + /// The terrain channel being saved + public override void SaveStream(Stream stream, ITerrainChannel map) + { + Bitmap colours = CreateGrayscaleBitmapFromMap(map); + + colours.Save(stream, ImageFormat.Png); + } public override string ToString() { diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/RAW32.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/RAW32.cs index 689abcf972..bb8b0f750c 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/RAW32.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/RAW32.cs @@ -41,22 +41,10 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders public ITerrainChannel LoadFile(string filename) { - TerrainChannel retval = new TerrainChannel(); - FileInfo file = new FileInfo(filename); FileStream s = file.Open(FileMode.Open, FileAccess.Read); - BinaryReader bs = new BinaryReader(s); - int y; - for (y = 0; y < retval.Height; y++) - { - int x; - for (x = 0; x < retval.Width; x++) - { - retval[x, y] = bs.ReadSingle(); - } - } + ITerrainChannel retval = LoadStream(s); - bs.Close(); s.Close(); return retval; @@ -124,11 +112,38 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders return retval; } + + public ITerrainChannel LoadStream(Stream s) + { + TerrainChannel retval = new TerrainChannel(); + + BinaryReader bs = new BinaryReader(s); + int y; + for (y = 0; y < retval.Height; y++) + { + int x; + for (x = 0; x < retval.Width; x++) + { + retval[x, y] = bs.ReadSingle(); + } + } + bs.Close(); + + return retval; + } + public void SaveFile(string filename, ITerrainChannel map) { FileInfo file = new FileInfo(filename); FileStream s = file.Open(FileMode.Create, FileAccess.Write); + SaveStream(s, map); + + s.Close(); + } + + public void SaveStream(Stream s, ITerrainChannel map) + { BinaryWriter bs = new BinaryWriter(s); int y; @@ -141,8 +156,7 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders } } - bs.Close(); - s.Close(); + bs.Close(); } #endregion diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/TIFF.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/TIFF.cs index c081aea04c..3f98f40ce1 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/TIFF.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/TIFF.cs @@ -24,8 +24,10 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System.Drawing; using System.Drawing.Imaging; +using System.IO; using OpenSim.Region.Environment.Interfaces; namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders @@ -38,6 +40,18 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders colours.Save(filename, ImageFormat.Tiff); } + + /// + /// Exports a stream using a System.Drawing exporter. + /// + /// The target stream + /// The terrain channel being saved + public override void SaveStream(Stream stream, ITerrainChannel map) + { + Bitmap colours = CreateGrayscaleBitmapFromMap(map); + + colours.Save(stream, ImageFormat.Tiff); + } public override string ToString() { diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/Terragen.cs b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/Terragen.cs index fe36cf7365..5dc2aa5274 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/Terragen.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/FileLoaders/Terragen.cs @@ -43,10 +43,19 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders public ITerrainChannel LoadFile(string filename) { - TerrainChannel retval = new TerrainChannel(); - FileInfo file = new FileInfo(filename); FileStream s = file.Open(FileMode.Open, FileAccess.Read); + ITerrainChannel retval = LoadStream(s); + + s.Close(); + + return retval; + } + + public ITerrainChannel LoadStream(Stream s) + { + TerrainChannel retval = new TerrainChannel(); + BinaryReader bs = new BinaryReader(s); bool eof = false; @@ -98,8 +107,7 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders } bs.Close(); - s.Close(); - + return retval; } @@ -107,6 +115,11 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain.FileLoaders { throw new NotImplementedException(); } + + public void SaveStream(Stream stream, ITerrainChannel map) + { + throw new NotImplementedException(); + } public string FileExtension { diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainLoader.cs b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainLoader.cs index 4c16c1c30d..950b27ba49 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainLoader.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainLoader.cs @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System.IO; using OpenSim.Region.Environment.Interfaces; namespace OpenSim.Region.Environment.Modules.World.Terrain @@ -34,6 +35,8 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain string FileExtension { get; } ITerrainChannel LoadFile(string filename); ITerrainChannel LoadFile(string filename, int fileStartX, int fileStartY, int fileWidth, int fileHeight, int sectionWidth, int sectionHeight); + ITerrainChannel LoadStream(Stream stream); void SaveFile(string filename, ITerrainChannel map); + void SaveStream(Stream stream, ITerrainChannel map); } } \ No newline at end of file diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainModule.cs b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainModule.cs index 6ab2372201..e255515698 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/ITerrainModule.cs @@ -25,12 +25,33 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +using System.IO; + namespace OpenSim.Region.Environment.Modules.World.Terrain { public interface ITerrainModule { void LoadFromFile(string filename); void SaveToFile(string filename); + + /// + /// Load a terrain from a stream. + /// + /// + /// Only required here to identify the image type. Not otherwise used in the loading itself. + /// + /// + void LoadFromStream(string filename, Stream stream); + + /// + /// Save a terrain to a stream. + /// + /// + /// Only required here to identify the image type. Not otherwise used in the saving itself. + /// + /// + void SaveToStream(string filename, Stream stream); + void InstallPlugin(string name, ITerrainEffect plug); } } diff --git a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs index 1bda2a096f..fb81abcf65 100644 --- a/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs +++ b/OpenSim/Region/Environment/Modules/World/Terrain/TerrainModule.cs @@ -221,6 +221,67 @@ namespace OpenSim.Region.Environment.Modules.World.Terrain throw new TerrainException(String.Format("Unable to save heightmap: saving of this file format not implemented")); } } + + /// + /// Loads a terrain file from a stream and installs it in the scene. + /// + /// Filename to terrain file. Type is determined by extension. + /// + public void LoadFromStream(string filename, Stream stream) + { + foreach (KeyValuePair loader in m_loaders) + { + if (filename.EndsWith(loader.Key)) + { + lock (m_scene) + { + try + { + ITerrainChannel channel = loader.Value.LoadStream(stream); + m_scene.Heightmap = channel; + m_channel = channel; + UpdateRevertMap(); + } + catch (NotImplementedException) + { + m_log.Error("[TERRAIN]: Unable to load heightmap, the " + loader.Value + + " parser does not support file loading. (May be save only)"); + throw new TerrainException(String.Format("unable to load heightmap: parser {0} does not support loading", loader.Value)); + } + } + CheckForTerrainUpdates(); + m_log.Info("[TERRAIN]: File (" + filename + ") loaded successfully"); + return; + } + } + m_log.Error("[TERRAIN]: Unable to load heightmap, no file loader availible for that format."); + throw new TerrainException(String.Format("unable to load heightmap from file {0}: no loader available for that format", filename)); + } + + /// + /// Saves the current heightmap to a specified stream. + /// + /// The destination filename. Used here only to identify the image type + /// + public void SaveToStream(string filename, Stream stream) + { + try + { + foreach (KeyValuePair loader in m_loaders) + { + if (filename.EndsWith(loader.Key)) + { + loader.Value.SaveStream(stream, m_channel); + return; + } + } + } + catch (NotImplementedException) + { + m_log.Error("Unable to save to " + filename + ", saving of this file format has not been implemented."); + throw new TerrainException(String.Format("Unable to save heightmap: saving of this file format not implemented")); + } + } #region Plugin Loading Methods