diff --git a/source2/Users/Orvid/ImageManipulatorTester/..svnbridge/Test.gif b/source2/Users/Orvid/ImageManipulatorTester/..svnbridge/Test.gif
new file mode 100644
index 000000000..08149303f
--- /dev/null
+++ b/source2/Users/Orvid/ImageManipulatorTester/..svnbridge/Test.gif
@@ -0,0 +1 @@
+svn:mime-typeapplication/octet-stream
\ No newline at end of file
diff --git a/source2/Users/Orvid/ImageManipulatorTester/Form1.cs b/source2/Users/Orvid/ImageManipulatorTester/Form1.cs
index 506a6726a..6f88be050 100644
--- a/source2/Users/Orvid/ImageManipulatorTester/Form1.cs
+++ b/source2/Users/Orvid/ImageManipulatorTester/Form1.cs
@@ -12,6 +12,7 @@ namespace ImageManipulatorTester
public partial class Form1 : System.Windows.Forms.Form
{
private StreamWriter st;
+
public Form1()
{
InitializeComponent();
@@ -363,10 +364,51 @@ namespace ImageManipulatorTester
System.GC.Collect();
+ #region Load Gif
+ {
+ FileStream s = new FileStream(Path.GetFullPath("Test.gif"), FileMode.Open);
+
+ t.Start();
+ anim = Orvid.Graphics.ImageFormats.GifSupport.Load(s);
+ t.Stop();
+ WriteToLog("Loading a Gif took '" + t.ElapsedMilliseconds.ToString() + " ms'");
+ t.Reset();
+
+ s.Close();
+ s.Dispose();
+
+ Bitmap b = (Bitmap)anim[0];
+ GifPictureBox = new PictureBox();
+ GifPictureBox.BorderStyle = BorderStyle.FixedSingle;
+ GifPictureBox.Parent = flowLayoutPanel2;
+ GifPictureBox.Height = b.Height;
+ GifPictureBox.Width = b.Width;
+ GifPictureBox.Image = b;
+ animpar = new Orvid.Graphics.Shapes.ShapedImage(anim.Width, anim.Height);
+ anim.Parent = animpar;
+ animpar.Shapes.Add(anim);
+
+ //time.Interval = anim.TimePerFrame * 4;
+ //time.Tick += new EventHandler(time_Tick);
+ //time.Start();
+ }
+ #endregion
+
st.Flush();
st.Close();
st.Dispose();
}
+
+ private PictureBox GifPictureBox;
+ private Orvid.Graphics.AnimatedImage anim;
+ private Orvid.Graphics.Shapes.ShapedImage animpar;
+ private Timer time = new Timer();
+ private void time_Tick(object sender, EventArgs e)
+ {
+ animpar.Modified = true;
+ GifPictureBox.Image = (Bitmap)animpar.Render();
+ GifPictureBox.Refresh();
+ }
}
}
diff --git a/source2/Users/Orvid/ImageManipulatorTester/Test.gif b/source2/Users/Orvid/ImageManipulatorTester/Test.gif
new file mode 100644
index 000000000..2a97f6dbc
Binary files /dev/null and b/source2/Users/Orvid/ImageManipulatorTester/Test.gif differ
diff --git a/source2/Users/Orvid/Orvid.Graphics/AnimatedImage.cs b/source2/Users/Orvid/Orvid.Graphics/AnimatedImage.cs
new file mode 100644
index 000000000..5ef73398a
--- /dev/null
+++ b/source2/Users/Orvid/Orvid.Graphics/AnimatedImage.cs
@@ -0,0 +1,122 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Orvid.Graphics
+{
+ public class AnimatedImage : Shapes.Shape, IDisposable
+ {
+ public Image[] Frames;
+ private UInt32 curFrameIndex;
+ private bool loop = false;
+ public int Height { get { return Frames[0].Height; } }
+ public int Width { get { return Frames[0].Width; } }
+
+ ///
+ /// This is in Milli-Seconds
+ ///
+ public int TimePerFrame { get; set; }
+
+ public bool Loop
+ {
+ get
+ {
+ return loop;
+ }
+ set
+ {
+ loop = value;
+ }
+ }
+
+ public UInt32 CurFrameIndex
+ {
+ get
+ {
+ return curFrameIndex;
+ }
+ set
+ {
+ SetCurrrentFrameIndex(value);
+ }
+ }
+
+ public Image this[UInt32 val]
+ {
+ get
+ {
+ return GetFrame(val);
+ }
+ set
+ {
+ SetFrame(val, value);
+ }
+ }
+
+ public void SetFrame(UInt32 indx, Image i)
+ {
+ if (indx < Frames.Length)
+ Frames[indx] = i;
+ throw new Exception("Specified Frame Doesn't Exist!");
+ }
+
+ public AnimatedImage()
+ {
+ Frames = new Image[0];
+ }
+
+ public AnimatedImage(Image[] images)
+ {
+ Frames = new Image[images.Length];
+ Array.Copy(images, Frames, images.Length);
+ curFrameIndex = 0;
+ }
+
+ public Image GetFrame(UInt32 indx)
+ {
+ if (indx < Frames.Length)
+ return Frames[indx];
+ throw new Exception("Specified Frame Doesn't Exist!");
+ }
+
+ public void AddFrame(Image i)
+ {
+ Image[] tmp = new Image[Frames.Length + 1];
+ Array.Copy(Frames, tmp, Frames.Length);
+ tmp[tmp.Length - 1] = i;
+ Frames = tmp;
+ curFrameIndex = 1;
+ }
+
+ public void SetCurrrentFrameIndex(uint v)
+ {
+ if (v < Frames.Length - 1)
+ curFrameIndex = v;
+ else
+ throw new Exception("Specified Frame Non-Existant!");
+ }
+
+ public override void Draw()
+ {
+ Parent.Clear(new Pixel(true));
+ Parent.DrawImage(new Vec2(this.X, this.Y), Frames[curFrameIndex]);
+
+ if (curFrameIndex + 2 <= Frames.Length - 1)
+ {
+ curFrameIndex++;
+ curFrameIndex++;
+ }
+ else// if (loop)
+ {
+ curFrameIndex = 0;
+ }
+
+ this.Modified = true;
+ }
+
+ public void Dispose()
+ {
+ this.Frames = null;
+ }
+ }
+}
diff --git a/source2/Users/Orvid/Orvid.Graphics/ImageFormats/FormatManager.cs b/source2/Users/Orvid/Orvid.Graphics/ImageFormats/FormatManager.cs
index 977b93205..0ec778aae 100644
--- a/source2/Users/Orvid/Orvid.Graphics/ImageFormats/FormatManager.cs
+++ b/source2/Users/Orvid/Orvid.Graphics/ImageFormats/FormatManager.cs
@@ -15,6 +15,7 @@ namespace Orvid.Graphics.ImageFormats
Formats.Add(new VbpImage());
Formats.Add(new JpegImage());
Formats.Add(new TiffImage());
+ Formats.Add(new TgaImage());
}
}
diff --git a/source2/Users/Orvid/Orvid.Graphics/ImageFormats/GifSupport.cs b/source2/Users/Orvid/Orvid.Graphics/ImageFormats/GifSupport.cs
new file mode 100644
index 000000000..dd1cbabd2
--- /dev/null
+++ b/source2/Users/Orvid/Orvid.Graphics/ImageFormats/GifSupport.cs
@@ -0,0 +1,646 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.IO;
+
+namespace Orvid.Graphics.ImageFormats
+{
+ public static class GifSupport
+ {
+ public static AnimatedImage Load(Stream s)
+ {
+ GifDecoder g = new GifDecoder();
+ return g.DecodeImage(s);
+ }
+
+
+ // Please note, everything below this
+ // point was originally from the ImageTools
+ // Library, available here:
+ // http://imagetools.codeplex.com/
+ //
+ // This disclaimer was last
+ // modified on August 7, 2011.
+
+
+
+ #region Internals
+
+ #region DisposalMethod
+ ///
+ /// Specifies, what to do with the last image
+ /// in an animation sequence.
+ ///
+ private enum DisposalMethod : int
+ {
+ ///
+ /// No disposal specified. The decoder is not
+ /// required to take any action.
+ ///
+ Unspecified = 0,
+ ///
+ /// Do not dispose. The graphic is to be left in place.
+ ///
+ NotDispose = 1,
+ ///
+ /// Restore to background color.
+ /// The area used by the graphic must be restored to
+ /// the background color.
+ ///
+ RestoreToBackground = 2,
+ ///
+ /// Restore to previous. The decoder is required to
+ /// restore the area overwritten by the
+ /// graphic with what was there prior to rendering the graphic.
+ ///
+ RestoreToPrevious = 3
+ }
+ #endregion
+
+ #region GifDecoder
+ private class GifDecoder
+ {
+ private const byte ExtensionIntroducer = 0x21;
+ private const byte Terminator = 0;
+ private const byte ImageLabel = 0x2C;
+ private const byte EndIntroducer = 0x3B;
+ private const byte ApplicationExtensionLabel = 0xFF;
+ private const byte CommentLabel = 0xFE;
+ private const byte ImageDescriptorLabel = 0x2C;
+ private const byte PlainTextLabel = 0x01;
+ private const byte GraphicControlLabel = 0xF9;
+ private AnimatedImage _image;
+ private Stream _stream;
+ private GifLogicalScreenDescriptor _logicalScreenDescriptor;
+ private byte[] _globalColorTable;
+ private byte[] _currentFrame;
+ private GifGraphicsControlExtension _graphicsControl;
+
+
+ public AnimatedImage DecodeImage(Stream stream)
+ {
+ _image = new AnimatedImage();
+
+ _stream = stream;
+ _stream.Seek(6, SeekOrigin.Current);
+
+ ReadLogicalScreenDescriptor();
+
+ if (_logicalScreenDescriptor.GlobalColorTableFlag == true)
+ {
+ _globalColorTable = new byte[_logicalScreenDescriptor.GlobalColorTableSize * 3];
+
+ // Read the global color table from the stream
+ stream.Read(_globalColorTable, 0, _globalColorTable.Length);
+ }
+
+ int nextFlag = stream.ReadByte();
+ while (nextFlag != 0)
+ {
+ if (nextFlag == ImageLabel)
+ {
+ ReadFrame();
+ }
+ else if (nextFlag == ExtensionIntroducer)
+ {
+ int gcl = stream.ReadByte();
+ switch (gcl)
+ {
+ case GraphicControlLabel:
+ ReadGraphicalControlExtension();
+ break;
+ case CommentLabel:
+ ReadComments();
+ break;
+ case ApplicationExtensionLabel:
+ Skip(12);
+ break;
+ case PlainTextLabel:
+ Skip(13);
+ break;
+ }
+ }
+ else if (nextFlag == EndIntroducer)
+ {
+ break;
+ }
+ nextFlag = stream.ReadByte();
+ }
+ return _image;
+ }
+
+ private void ReadGraphicalControlExtension()
+ {
+ byte[] buffer = new byte[6];
+
+ _stream.Read(buffer, 0, buffer.Length);
+
+ byte packed = buffer[1];
+
+ _graphicsControl = new GifGraphicsControlExtension();
+ _graphicsControl.DelayTime = BitConverter.ToInt16(buffer, 2);
+ _graphicsControl.TransparencyIndex = buffer[4];
+ _graphicsControl.TransparencyFlag = (packed & 0x01) == 1;
+ _graphicsControl.DisposalMethod = (DisposalMethod)((packed & 0x1C) >> 2);
+ }
+
+ private GifImageDescriptor ReadImageDescriptor()
+ {
+ byte[] buffer = new byte[9];
+
+ _stream.Read(buffer, 0, buffer.Length);
+
+ byte packed = buffer[8];
+
+ GifImageDescriptor imageDescriptor = new GifImageDescriptor();
+ imageDescriptor.Left = BitConverter.ToInt16(buffer, 0);
+ imageDescriptor.Top = BitConverter.ToInt16(buffer, 2);
+ imageDescriptor.Width = BitConverter.ToInt16(buffer, 4);
+ imageDescriptor.Height = BitConverter.ToInt16(buffer, 6);
+ imageDescriptor.LocalColorTableFlag = ((packed & 0x80) >> 7) == 1;
+ imageDescriptor.LocalColorTableSize = 2 << (packed & 0x07);
+ imageDescriptor.InterlaceFlag = ((packed & 0x40) >> 6) == 1;
+
+ return imageDescriptor;
+ }
+
+ private void ReadLogicalScreenDescriptor()
+ {
+ byte[] buffer = new byte[7];
+
+ _stream.Read(buffer, 0, buffer.Length);
+
+ byte packed = buffer[4];
+
+ _logicalScreenDescriptor = new GifLogicalScreenDescriptor();
+ _logicalScreenDescriptor.Width = BitConverter.ToInt16(buffer, 0);
+ _logicalScreenDescriptor.Height = BitConverter.ToInt16(buffer, 2);
+ _logicalScreenDescriptor.Background = buffer[5];
+ _logicalScreenDescriptor.GlobalColorTableFlag = ((packed & 0x80) >> 7) == 1;
+ _logicalScreenDescriptor.GlobalColorTableSize = 2 << (packed & 0x07);
+ }
+
+ private void Skip(int length)
+ {
+ _stream.Seek(length, SeekOrigin.Current);
+
+ int flag = 0;
+
+ while ((flag = _stream.ReadByte()) != 0)
+ {
+ _stream.Seek(flag, SeekOrigin.Current);
+ }
+ }
+
+ private void ReadComments()
+ {
+ int flag = 0;
+
+ while ((flag = _stream.ReadByte()) != 0)
+ {
+ byte[] buffer = new byte[flag];
+ _stream.Read(buffer, 0, flag);
+ }
+ }
+
+ private void ReadFrame()
+ {
+ GifImageDescriptor imageDescriptor = ReadImageDescriptor();
+
+ byte[] localColorTable = ReadFrameLocalColorTable(imageDescriptor);
+
+ byte[] indices = ReadFrameIndices(imageDescriptor);
+
+ // Determine the color table for this frame. If there is a local one, use it
+ // otherwise use the global color table.
+ byte[] colorTable = localColorTable != null ? localColorTable : _globalColorTable;
+
+ ReadFrameColors(indices, colorTable, imageDescriptor);
+
+ int blockSize = _stream.ReadByte();
+ if (blockSize > 0)
+ {
+ _stream.Seek(blockSize, SeekOrigin.Current);
+ }
+ }
+
+ private byte[] ReadFrameIndices(GifImageDescriptor imageDescriptor)
+ {
+ int dataSize = _stream.ReadByte();
+
+ LZWDecoder lzwDecoder = new LZWDecoder(_stream);
+
+ byte[] indices = lzwDecoder.DecodePixels(imageDescriptor.Width, imageDescriptor.Height, dataSize);
+ return indices;
+ }
+
+ private byte[] ReadFrameLocalColorTable(GifImageDescriptor imageDescriptor)
+ {
+ byte[] localColorTable = null;
+
+ if (imageDescriptor.LocalColorTableFlag == true)
+ {
+ localColorTable = new byte[imageDescriptor.LocalColorTableSize * 3];
+
+ _stream.Read(localColorTable, 0, localColorTable.Length);
+ }
+
+ return localColorTable;
+ }
+
+ private void ReadFrameColors(byte[] indices, byte[] colorTable, GifImageDescriptor descriptor)
+ {
+ int imageWidth = _logicalScreenDescriptor.Width;
+ int imageHeight = _logicalScreenDescriptor.Height;
+
+ if (_currentFrame == null)
+ {
+ _currentFrame = new byte[imageWidth * imageHeight * 4];
+ }
+
+ byte[] lastFrame = null;
+
+ if (_graphicsControl != null &&
+ _graphicsControl.DisposalMethod == DisposalMethod.RestoreToPrevious)
+ {
+ lastFrame = new byte[imageWidth * imageHeight * 4];
+
+ Array.Copy(_currentFrame, lastFrame, lastFrame.Length);
+ }
+
+ int offset = 0, i = 0, index = -1;
+
+ int iPass = 0; // the interlace pass
+ int iInc = 8; // the interlacing line increment
+ int iY = 0; // the current interlaced line
+ int writeY = 0; // the target y offset to write to
+
+ for (int y = descriptor.Top; y < descriptor.Top + descriptor.Height; y++)
+ {
+ // Check if this image is interlaced.
+ if (descriptor.InterlaceFlag)
+ {
+ // If so then we read lines at predetermined offsets.
+ // When an entire image height worth of offset lines has been read we consider this a pass.
+ // With each pass the number of offset lines changes and the starting line changes.
+ if (iY >= descriptor.Height)
+ {
+ iPass++;
+ switch (iPass)
+ {
+ case 1:
+ iY = 4;
+ break;
+ case 2:
+ iY = 2;
+ iInc = 4;
+ break;
+ case 3:
+ iY = 1;
+ iInc = 2;
+ break;
+ }
+ }
+
+ writeY = iY + descriptor.Top;
+
+ iY += iInc;
+ }
+ else
+ {
+ writeY = y;
+ }
+
+ for (int x = descriptor.Left; x < descriptor.Left + descriptor.Width; x++)
+ {
+ offset = writeY * imageWidth + x;
+
+ index = indices[i];
+
+ if (_graphicsControl == null ||
+ _graphicsControl.TransparencyFlag == false ||
+ _graphicsControl.TransparencyIndex != index)
+ {
+ _currentFrame[offset * 4 + 0] = colorTable[index * 3 + 0];
+ _currentFrame[offset * 4 + 1] = colorTable[index * 3 + 1];
+ _currentFrame[offset * 4 + 2] = colorTable[index * 3 + 2];
+ _currentFrame[offset * 4 + 3] = (byte)255;
+ }
+
+ i++;
+ }
+ }
+
+ byte[] pixels = new byte[imageWidth * imageHeight * 4];
+
+ Array.Copy(_currentFrame, pixels, pixels.Length);
+ _currentFrame = new byte[imageWidth * imageHeight * 4];
+ Image frame = new Image(imageWidth, imageHeight);
+
+ int indx = 0;
+ byte r, g, b, a;
+ for (uint y = 0; y < frame.Height; y++)
+ {
+ for (uint x = 0; x < frame.Width; x++)
+ {
+ r = pixels[indx];
+ indx++;
+ g = pixels[indx];
+ indx++;
+ b = pixels[indx];
+ indx++;
+ a = pixels[indx];
+ indx++;
+ frame.SetPixel(x, y, new Pixel(r, g, b, a));
+ }
+ }
+ pixels = null;
+ System.GC.Collect();
+ _image.AddFrame(frame);
+
+
+ if (_graphicsControl != null)
+ {
+ if (_graphicsControl.DelayTime > 0)
+ {
+ _image.TimePerFrame = _graphicsControl.DelayTime;
+ }
+
+ if (_graphicsControl.DisposalMethod == DisposalMethod.RestoreToBackground)
+ {
+ Image im = new Image(imageWidth, imageHeight);
+ im.Clear(new Pixel(true));
+ _image.AddFrame(im);
+ _image.Loop = false;
+
+ }
+ else if (_graphicsControl.DisposalMethod == DisposalMethod.RestoreToPrevious)
+ {
+ _image.Loop = true;
+ }
+ }
+ }
+ }
+ #endregion
+
+ #region GifImageDescriptor
+ private sealed class GifImageDescriptor
+ {
+ ///
+ /// Column number, in pixels, of the left edge of the image,
+ /// with respect to the left edge of the Logical Screen.
+ /// Leftmost column of the Logical Screen is 0.
+ ///
+ public short Left;
+ ///
+ /// Row number, in pixels, of the top edge of the image with
+ /// respect to the top edge of the Logical Screen.
+ /// Top row of the Logical Screen is 0.
+ ///
+ public short Top;
+ ///
+ /// Width of the image in pixels.
+ ///
+ public short Width;
+ ///
+ /// Height of the image in pixels.
+ ///
+ public short Height;
+ ///
+ /// Indicates the presence of a Local Color Table immediately
+ /// following this Image Descriptor.
+ ///
+ public bool LocalColorTableFlag;
+ ///
+ /// If the Local Color Table Flag is set to 1, the value in this field
+ /// is used to calculate the number of bytes contained in the Local Color Table.
+ ///
+ public int LocalColorTableSize;
+ ///
+ /// Indicates if the image is interlaced. An image is interlaced
+ /// in a four-pass interlace pattern.
+ ///
+ public bool InterlaceFlag;
+ }
+ #endregion
+
+ #region GifLogicalScreenDescriptor
+ private sealed class GifLogicalScreenDescriptor
+ {
+ ///
+ /// Width, in pixels, of the Logical Screen where the images will
+ /// be rendered in the displaying device.
+ ///
+ public short Width;
+ ///
+ /// Height, in pixels, of the Logical Screen where the images will be
+ /// rendered in the displaying device.
+ ///
+ public short Height;
+ ///
+ /// Index into the Global Color Table for the Background Color.
+ /// The Background Color is the color used for those
+ /// pixels on the screen that are not covered by an image.
+ ///
+ public byte Background;
+ ///
+ /// Flag indicating the presence of a Global Color Table;
+ /// if the flag is set, the Global Color Table will immediately
+ /// follow the Logical Screen Descriptor.
+ ///
+ public bool GlobalColorTableFlag;
+ ///
+ /// If the Global Color Table Flag is set to 1,
+ /// the value in this field is used to calculate the number of
+ /// bytes contained in the Global Color Table.
+ ///
+ public int GlobalColorTableSize;
+ }
+ #endregion
+
+ #region GifGraphicsControlExtension
+ private sealed class GifGraphicsControlExtension
+ {
+ ///
+ /// Indicates the way in which the graphic is to be treated after being displayed.
+ ///
+ public DisposalMethod DisposalMethod;
+ ///
+ /// Indicates whether a transparency index is given in the Transparent Index field.
+ /// (This field is the least significant bit of the byte.)
+ ///
+ public bool TransparencyFlag;
+ ///
+ /// The Transparency Index is such that when encountered, the corresponding pixel
+ /// of the display device is not modified and processing goes on to the next pixel.
+ ///
+ public int TransparencyIndex;
+ ///
+ /// If not 0, this field specifies the number of hundredths (1/100) of a second to
+ /// wait before continuing with the processing of the Data Stream.
+ /// The clock starts ticking immediately after the graphic is rendered.
+ /// This field may be used in conjunction with the User Input Flag field.
+ ///
+ public int DelayTime;
+ }
+ #endregion
+
+ #region LZWDecoder
+ private sealed class LZWDecoder
+ {
+ private const int StackSize = 4096;
+ private const int NullCode = -1;
+
+ private Stream _stream;
+
+ ///
+ /// Initializes a new instance of the class
+ /// and sets the stream, where the compressed data should be read from.
+ ///
+ /// The stream. where to read from.
+ /// is null
+ /// (Nothing in Visual Basic).
+ public LZWDecoder(Stream stream)
+ {
+ _stream = stream;
+ }
+
+ ///
+ /// Decodes and uncompresses all pixel indices from the stream.
+ ///
+ /// The width of the pixel index array.
+ /// The height of the pixel index array.
+ /// Size of the data.
+ /// The decoded and uncompressed array.
+ public byte[] DecodePixels(int width, int height, int dataSize)
+ {
+ byte[] pixels = new byte[width * height];
+ int clearCode = 1 << dataSize;
+ if (dataSize == Int32.MaxValue)
+ {
+ throw new ArgumentOutOfRangeException("dataSize", "Must be less than Int32.MaxValue");
+ }
+ int codeSize = dataSize + 1;
+ int endCode = clearCode + 1;
+ int availableCode = clearCode + 2;
+ #region Jillzhangs Code (Not From Me) see: http://giflib.codeplex.com/
+ int code = NullCode;
+ int old_code = NullCode;
+ int code_mask = (1 << codeSize) - 1;
+ int bits = 0;
+ int[] prefix = new int[StackSize];
+ int[] suffix = new int[StackSize];
+ int[] pixelStatck = new int[StackSize + 1];
+ int top = 0;
+ int count = 0;
+ int bi = 0;
+ int xyz = 0;
+ int data = 0;
+ int first = 0;
+ int inCode = NullCode;
+ for (code = 0; code < clearCode; code++)
+ {
+ prefix[code] = 0;
+ suffix[code] = (byte)code;
+ }
+
+ byte[] buffer = null;
+ while (xyz < pixels.Length)
+ {
+ if (top == 0)
+ {
+ if (bits < codeSize)
+ {
+ if (count == 0)
+ {
+ buffer = ReadBlock();
+ count = buffer.Length;
+ if (count == 0)
+ {
+ break;
+ }
+ bi = 0;
+ }
+ data += buffer[bi] << bits;
+ bits += 8;
+ bi++;
+ count--;
+ continue;
+ }
+ code = data & code_mask;
+ data >>= codeSize;
+ bits -= codeSize;
+ if (code > availableCode || code == endCode)
+ {
+ break;
+ }
+ if (code == clearCode)
+ {
+ codeSize = dataSize + 1;
+ code_mask = (1 << codeSize) - 1;
+ availableCode = clearCode + 2;
+ old_code = NullCode;
+ continue;
+ }
+ if (old_code == NullCode)
+ {
+ pixelStatck[top++] = suffix[code];
+ old_code = code;
+ first = code;
+ continue;
+ }
+ inCode = code;
+ if (code == availableCode)
+ {
+ pixelStatck[top++] = (byte)first;
+ code = old_code;
+ }
+ while (code > clearCode)
+ {
+ pixelStatck[top++] = suffix[code];
+ code = prefix[code];
+ }
+ first = suffix[code];
+ if (availableCode > StackSize)
+ {
+ break;
+ }
+ pixelStatck[top++] = suffix[code];
+ prefix[availableCode] = old_code;
+ suffix[availableCode] = first;
+ availableCode++;
+ if (availableCode == code_mask + 1 && availableCode < StackSize)
+ {
+ codeSize++;
+ code_mask = (1 << codeSize) - 1;
+ }
+ old_code = inCode;
+ }
+ top--;
+ pixels[xyz++] = (byte)pixelStatck[top];
+ }
+
+ #endregion
+
+ return pixels;
+ }
+
+ private byte[] ReadBlock()
+ {
+ int blockSize = _stream.ReadByte();
+ return ReadBytes(blockSize);
+ }
+
+ private byte[] ReadBytes(int length)
+ {
+ byte[] buffer = new byte[length];
+ _stream.Read(buffer, 0, length);
+ return buffer;
+ }
+ }
+ #endregion
+
+ #endregion
+ }
+
+}
diff --git a/source2/Users/Orvid/Orvid.Graphics/Orvid.Graphics.csproj b/source2/Users/Orvid/Orvid.Graphics/Orvid.Graphics.csproj
index 19dbb5974..b1f1634c1 100644
--- a/source2/Users/Orvid/Orvid.Graphics/Orvid.Graphics.csproj
+++ b/source2/Users/Orvid/Orvid.Graphics/Orvid.Graphics.csproj
@@ -42,6 +42,7 @@
+
@@ -56,6 +57,7 @@
+
diff --git a/source2/Users/Orvid/Orvid.Graphics/Shapes/Shape.cs b/source2/Users/Orvid/Orvid.Graphics/Shapes/Shape.cs
index a5b2073b1..35664cf98 100644
--- a/source2/Users/Orvid/Orvid.Graphics/Shapes/Shape.cs
+++ b/source2/Users/Orvid/Orvid.Graphics/Shapes/Shape.cs
@@ -49,7 +49,7 @@ namespace Orvid.Graphics.Shapes
}
}
}
- public ShapedImage Parent { get; protected set; }
+ public ShapedImage Parent { get; set; }
public abstract void Draw();
}
}
diff --git a/source2/Users/Orvid/Orvid.Graphics/Shapes/ShapedImage.cs b/source2/Users/Orvid/Orvid.Graphics/Shapes/ShapedImage.cs
index dd2bb7aa5..5e2a3eac8 100644
--- a/source2/Users/Orvid/Orvid.Graphics/Shapes/ShapedImage.cs
+++ b/source2/Users/Orvid/Orvid.Graphics/Shapes/ShapedImage.cs
@@ -6,8 +6,8 @@ namespace Orvid.Graphics.Shapes
{
public class ShapedImage : Image
{
- public bool Modified { get; internal set; }
- internal List Shapes = new List();
+ public bool Modified { get; set; }
+ public List Shapes = new List();
public ShapedImage(int width, int height) : base(width, height)
{