From 9d52d175e032f0234a7cc4edb6dd652ec2d085eb Mon Sep 17 00:00:00 2001 From: blah38621_cp <36925b492f9af1e8e676baa1ba817f9639f49ec7y44YxFx5> Date: Mon, 1 Aug 2011 02:19:23 +0000 Subject: [PATCH] Added the support for the first of many image formats Orvid.Graphics will eventually be able to handle. The format is custom, and is very plain. The file essentially contains the height, and width of the image, then the pixels of the image in rgba succession. (each component is a byte) Finally, the bytes that this produces are compressed using LZMA compression, producing a very basic, but usable format. Next will be an animated version, as well as support for animated images in the library. --- .../ImageFormats/ImageFormat.cs | 27 +++++ .../Orvid.Graphics/ImageFormats/OIFSupport.cs | 98 +++++++++++++++++++ .../Orvid.Graphics/Orvid.Graphics.csproj | 2 + .../Orvid.Graphics/Shapes/ShapedImage.cs | 7 +- .../Orvid/Orvid.Graphics/Shapes/Square.cs | 27 +++-- 5 files changed, 151 insertions(+), 10 deletions(-) create mode 100644 source2/Users/Orvid/Orvid.Graphics/ImageFormats/ImageFormat.cs create mode 100644 source2/Users/Orvid/Orvid.Graphics/ImageFormats/OIFSupport.cs diff --git a/source2/Users/Orvid/Orvid.Graphics/ImageFormats/ImageFormat.cs b/source2/Users/Orvid/Orvid.Graphics/ImageFormats/ImageFormat.cs new file mode 100644 index 000000000..0d3a0ffc7 --- /dev/null +++ b/source2/Users/Orvid/Orvid.Graphics/ImageFormats/ImageFormat.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Orvid.Graphics.ImageFormats +{ + /// + /// This class represents any Image format, + /// and should be the base type for all drivers. + /// + public abstract class ImageFormat + { + /// + /// Save an image to the specified stream. + /// + /// The image to save. + /// The Stream to write to. + public abstract void Save(Image i, Stream dest); + /// + /// Load an image from the specified stream. + /// + /// The Stream to load from. + /// The loaded Image. + public abstract Image Load(Stream s); + } +} diff --git a/source2/Users/Orvid/Orvid.Graphics/ImageFormats/OIFSupport.cs b/source2/Users/Orvid/Orvid.Graphics/ImageFormats/OIFSupport.cs new file mode 100644 index 000000000..4123e532a --- /dev/null +++ b/source2/Users/Orvid/Orvid.Graphics/ImageFormats/OIFSupport.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.IO; + +namespace Orvid.Graphics.ImageFormats +{ + public class OIFSupport : ImageFormat + { + + public override void Save(Image i, System.IO.Stream dest) + { + MemoryStream m = new MemoryStream(); + m.WriteByte(0); +#warning Change this next byte to 255 if you update Image with UInt64 for width and height. + m.WriteByte(0); + m.WriteByte(0); + m.WriteByte(0); // Write the 8 empty bytes at the start of the file. + m.WriteByte(0); + m.WriteByte(0); + m.WriteByte(0); + m.WriteByte(0); + + byte[] dat = BitConverter.GetBytes(i.Height); // Write the height. + m.Write(dat, 0, dat.Length); + dat = BitConverter.GetBytes(i.Width); // Write the width. + m.Write(dat, 0, dat.Length); + + // Now to write the actual data. + Pixel p; + for (uint x = 0; x < i.Width; x++) + { + for (uint y = 0; y < i.Height; y++) + { + p = i.GetPixel(x, y); + m.WriteByte(p.R); + m.WriteByte(p.G); + m.WriteByte(p.B); + m.WriteByte(p.A); + } + } + dat = Orvid.Compression.LZMA.Compress(m.GetBuffer()); + dest.WriteByte(255); + dest.Write(dat, 0, dat.Length); + } + + private UInt32 ReadUInt32(byte[] data) + { + UInt32 r = 0; + + r += data[3]; + r <<= 8; + r += data[2]; + r <<= 8; + r += data[1]; + r <<= 8; + r += data[0]; + + return r; + } + + public override Image Load(System.IO.Stream s) + { + + if (s.ReadByte() == 255) + { + byte[] buf = new byte[s.Length - 1]; + s.Read(buf, 0, buf.Length); + s = new MemoryStream(Orvid.Compression.LZMA.Decompress(buf)); + } + else + { + s.Position = 0; + } + byte[] tmp = new byte[8]; + s.Read(tmp, 0, 8); // skip the 8 empty bytes at the start of the file. + tmp = new byte[4]; + s.Read(tmp, 0, 4); + uint Height = ReadUInt32(tmp); // Read the Height. + s.Read(tmp, 0, 4); + uint Width = ReadUInt32(tmp); // Read the Width. + Image i = new Image((int)Width, (int)Height); + byte r, g, b, a; + for (uint x = 0; x < Width; x++) + { + for (uint y = 0; y < Height; y++) + { + r = (byte)s.ReadByte(); + g = (byte)s.ReadByte(); + b = (byte)s.ReadByte(); + a = (byte)s.ReadByte(); + i.SetPixel(x, y, new Pixel(r, g, b, a)); + } + } + return i; + } + } +} diff --git a/source2/Users/Orvid/Orvid.Graphics/Orvid.Graphics.csproj b/source2/Users/Orvid/Orvid.Graphics/Orvid.Graphics.csproj index 835ebb3d0..7004b921c 100644 --- a/source2/Users/Orvid/Orvid.Graphics/Orvid.Graphics.csproj +++ b/source2/Users/Orvid/Orvid.Graphics/Orvid.Graphics.csproj @@ -52,6 +52,8 @@ Code + + diff --git a/source2/Users/Orvid/Orvid.Graphics/Shapes/ShapedImage.cs b/source2/Users/Orvid/Orvid.Graphics/Shapes/ShapedImage.cs index 9a7717270..dd2bb7aa5 100644 --- a/source2/Users/Orvid/Orvid.Graphics/Shapes/ShapedImage.cs +++ b/source2/Users/Orvid/Orvid.Graphics/Shapes/ShapedImage.cs @@ -17,7 +17,12 @@ namespace Orvid.Graphics.Shapes { if (Modified) { - + this.Clear(new Pixel(true)); + foreach (Shape s in Shapes) + { + s.Draw(); + } + this.Modified = false; } return this; } diff --git a/source2/Users/Orvid/Orvid.Graphics/Shapes/Square.cs b/source2/Users/Orvid/Orvid.Graphics/Shapes/Square.cs index e22d2de19..9082ce8f6 100644 --- a/source2/Users/Orvid/Orvid.Graphics/Shapes/Square.cs +++ b/source2/Users/Orvid/Orvid.Graphics/Shapes/Square.cs @@ -7,7 +7,7 @@ namespace Orvid.Graphics.Shapes public class Square : Shape { private Image i; - private Pixel fillColor = new Pixel(255, 255, 255, 0); // Initialize white. + private Pixel fillColor = new Pixel(255, 255, 255, 255); // Initialize white. public Pixel FillColor { get @@ -16,11 +16,14 @@ namespace Orvid.Graphics.Shapes } set { - Modified = true; - fillColor = value; + if (fillColor != value) + { + Modified = true; + fillColor = value; + } } } - private Pixel borderColor = new Pixel(0, 0, 0, 0); // Initialize black. + private Pixel borderColor = new Pixel(0, 0, 0, 255); // Initialize black. public Pixel BorderColor { get @@ -29,8 +32,11 @@ namespace Orvid.Graphics.Shapes } set { - Modified = true; - borderColor = value; + if (borderColor != value) + { + Modified = true; + borderColor = value; + } } } private int size; @@ -42,9 +48,12 @@ namespace Orvid.Graphics.Shapes } set { - Modified = true; - size = value; - i = new Image(this.Size, this.Size); + if (size != value) + { + Modified = true; + size = value; + i = new Image(this.Size, this.Size); + } } }