From 87c837658d509d0e2db5651bc3769bc2eddc719d Mon Sep 17 00:00:00 2001
From: blah38621_cp <36925b492f9af1e8e676baa1ba817f9639f49ec7y44YxFx5>
Date: Mon, 8 Aug 2011 19:55:53 +0000
Subject: [PATCH] Gif image support added.
---
.../..svnbridge/Test.gif | 1 +
.../Orvid/ImageManipulatorTester/Form1.cs | 42 ++
.../Orvid/ImageManipulatorTester/Test.gif | Bin 0 -> 20169 bytes
.../Orvid/Orvid.Graphics/AnimatedImage.cs | 122 ++++
.../ImageFormats/FormatManager.cs | 1 +
.../Orvid.Graphics/ImageFormats/GifSupport.cs | 646 ++++++++++++++++++
.../Orvid.Graphics/Orvid.Graphics.csproj | 2 +
.../Orvid/Orvid.Graphics/Shapes/Shape.cs | 2 +-
.../Orvid.Graphics/Shapes/ShapedImage.cs | 4 +-
9 files changed, 817 insertions(+), 3 deletions(-)
create mode 100644 source2/Users/Orvid/ImageManipulatorTester/..svnbridge/Test.gif
create mode 100644 source2/Users/Orvid/ImageManipulatorTester/Test.gif
create mode 100644 source2/Users/Orvid/Orvid.Graphics/AnimatedImage.cs
create mode 100644 source2/Users/Orvid/Orvid.Graphics/ImageFormats/GifSupport.cs
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 0000000000000000000000000000000000000000..2a97f6dbc3d76c056af95dba0f2002a905c8131e
GIT binary patch
literal 20169
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
+ /// 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)
{