Пример #1
0
            public Bitmap Get(int index)
            {
                lock (art.SyncRoot) {
                    if (art.Disposed)
                    {
                        throw new ObjectDisposedException("Art");
                    }

                    if (index < 0 || index >= Count)
                    {
                        throw new ArgumentOutOfRangeException("index");
                    }

                    if (art.changeList.ContainsKey(index + Offset))
                    {
                        return(art.changeList[index + Offset]);
                    }
                    else
                    {
                        IndexData indexData = art.indexFile.Get(index + Offset, false);
                        if (indexData.IsValid)
                        {
                            return(ReadFromStream(indexData));
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }
            }
Пример #2
0
        /// <summary>
        /// Adds data to the end of the list.
        /// </summary>
        /// <param name="data">New data.</param>
        /// <returns>Index of written data.</returns>
        /// <exception cref="System.ObjectDisposedException">Object has been disposed.</exception>
        public int Add(IndexData data)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("IndexFile");
            }

            list.Add(data);

            return(list.Count - 1);
        }
Пример #3
0
        /// <summary>
        /// Sets data at specified index.
        /// </summary>
        /// <param name="index">Index of data.</param>
        /// <param name="data">New data.</param>
        /// <param name="create">If true list is automaticly resized; otherwise exception is thrown.</param>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when create is false and index is less than zero or equal to or greater than Count.</exception>
        /// <exception cref="System.ObjectDisposedException">Object has been disposed.</exception>
        public void Set(int index, IndexData data, bool create)
        {
            if (Disposed)
            {
                throw new ObjectDisposedException("IndexFile");
            }

            if (index > list.Count && create)
            {
                Resize(index);
            }

            list[index] = data;
        }
Пример #4
0
        /// <summary>
        /// Writes a Tile bitmap (44x44) into specified file and returns structure with indexing information.
        /// </summary>
        /// <param name="stream">Stream where to write to.</param>
        /// <param name="bitmap">Bitmap to write. If null, returns invalid IndexData.</param>
        /// <returns>IndexData structure with indexing information.</returns>
        /// <remarks>It writes only diamond from source image, other is ignored.</remarks>
        public static IndexData WriteTile(Stream stream, Bitmap bitmap)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if (bitmap == null)
            {
                return(IndexData.Empty);
            }

            // Check bitmap
            if (bitmap.Height != 44 || bitmap.Width != 44)
            {
                throw new ArgumentException("Bitmap has incorrect size. Only allowed is 44x44.", "bitmap");
            }

            // Create index list
            IndexData indexdata = IndexData.Empty;

            indexdata.Lookup = (uint)stream.Position;
            indexdata.Extra  = 0;

            BinaryWriter writer = new BinaryWriter(stream);

            for (int y = 0; y < 22; y++)
            {
                int x      = 22 - (y + 1);
                int lenght = (y + 1) * 2;
                for (int i = 0; i < lenght; i++)
                {
                    writer.Write(UOColorConverter.FromColor(bitmap.GetPixel(x + i, y)));
                }
            }
            for (int y = 22; y < 44; y++)
            {
                int x      = y - 22;
                int lenght = (44 - y) * 2;
                for (int i = 0; i < lenght; i++)
                {
                    writer.Write(UOColorConverter.FromColor(bitmap.GetPixel(x + i, y)));
                }
            }

            indexdata.Lenght = (uint)stream.Position - indexdata.Lookup;

            return(indexdata);
        }
Пример #5
0
        /// <summary>
        /// Loads IndexFile object from file.
        /// </summary>
        /// <param name="file">File path.</param>
        public static IndexFile Load(string file)
        {
            Stream       stream = null;
            BinaryReader reader = null;

            try
            {
                stream = File.OpenRead(file);
                reader = new BinaryReader(stream);

                Trace.WriteLineIf((stream.Length % IndexData.Size) != 0, "IndexFile: File size is not multiple of 12.", "MulLib");

                IndexFile indexFile = new IndexFile();

                IndexData data = new IndexData();
                for (int i = 0; i < stream.Length / IndexData.Size; i++)
                {
                    data.Lookup = reader.ReadUInt32();
                    data.Lenght = reader.ReadUInt32();
                    data.Extra  = reader.ReadUInt32();

                    indexFile.list.Add(data);
                }

                Trace.WriteLine(String.Format("IndexFile: File \"{0}\" succesfully loaded.", file), "MulLib");
                return(indexFile);
            }
            catch (Exception e)
            {
                throw new Exception("Error loading IndexFile.", e);
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                }

                if (stream != null)
                {
                    stream.Close();
                }
            }
        }
Пример #6
0
        /// <summary>
        /// Stores this object to specified files.
        /// </summary>
        /// <param name="idxFile">Index file.</param>
        /// <param name="mulFile">Data file.</param>
        /// <exception cref="System.ObjectDisposedException">Object has been disposed.</exception>
        public void Save(string idxFile, string mulFile)
        {
            lock (syncRoot)
            {
                if (Disposed)
                {
                    throw new ObjectDisposedException("Skills");
                }

                IndexFile    indexFile   = null;
                Stream       stream      = null;
                BinaryWriter writer      = null;
                Stream       indexStream = null;

                try
                {
                    indexStream = File.Open(idxFile, FileMode.Create, FileAccess.Write, FileShare.None);

                    indexFile = new IndexFile();
                    stream    = File.OpenWrite(mulFile);
                    writer    = new BinaryWriter(stream);

                    IndexData indexData = new IndexData();

                    foreach (SkillData skillData in list)
                    {
                        indexData.Lookup = (uint)stream.Position;
                        indexData.Lenght = (uint)skillData.Name.Length + 1;
                        indexData.Extra  = skillData.Extra;

                        writer.Write(skillData.Action);
                        writer.Write(Encoding.ASCII.GetBytes(skillData.Name));

                        indexFile.Add(indexData);
                    }

                    indexFile.Resize(256);
                    indexFile.Save(indexStream);
                    Trace.WriteLine(String.Format("IndexFile: File \"{0}\" succesfully saved.", idxFile), "MulLib");

                    writer.Flush();

                    Trace.WriteLine(String.Format("Skills: File \"{0}\" succesfully saved.", mulFile), "MulLib");
                }
                catch (Exception e)
                {
                    throw new Exception("Error saving Skills.", e);
                }
                finally
                {
                    if (indexFile != null)
                    {
                        indexFile.Dispose();
                    }

                    if (indexStream != null)
                    {
                        indexStream.Close();
                    }

                    if (writer != null)
                    {
                        writer.Close();
                    }

                    if (stream != null)
                    {
                        stream.Close();
                    }
                }
            }
        }
Пример #7
0
 protected override Bitmap ReadFromStream(IndexData indexData)
 {
     art.dataStream.Seek(indexData.Lookup, SeekOrigin.Begin);
     return Art.ReadTile(art.dataStream);
 }
Пример #8
0
 protected abstract Bitmap ReadFromStream(IndexData indexData);
Пример #9
0
        /// <summary>
        /// Saves object to specified files.
        /// </summary>
        /// <param name="idxFile">Index file path.</param>
        /// <param name="mulFile">Data file path.</param>
        /// <remarks>
        /// If mulFile differs from currently loaded file, new file is optimized (data file is sorted and without empty entries).
        /// Otherwise file must be loaded with write access.
        /// </remarks>
        public void Save(string idxFile, string mulFile)
        {
            lock (syncRoot) {
                if (Disposed)
                    throw new ObjectDisposedException("Art");

                Stream indexStream = null;

                try {
                    indexStream = File.Open(idxFile, FileMode.Create, FileAccess.Write, FileShare.None);

                    if (String.Compare(mulFile, this.mulFile, StringComparison.InvariantCultureIgnoreCase) == 0) {
                        // Target data file is same as source file. File will not be optimized.
                        Stream dataStream = this.dataStream;

                        if (!dataStream.CanWrite)
                            throw new InvalidOperationException("Trying to save data to source file, that is not opened for Write access.");

                        foreach (KeyValuePair<int, Bitmap> pair in changeList) {
                            if (pair.Key < 16384) {
                                // Tile, can be saved to same location in data stream
                                IndexData indexData = indexFile.Get(pair.Key, true);
                                if (indexData.IsValid) {
                                    dataStream.Seek(indexData.Lookup, SeekOrigin.Begin);
                                    IndexData writtenData = Art.WriteTile(dataStream, pair.Value);

                                    Debug.Assert(writtenData.Lookup == indexData.Lookup, "writtenData.Lookup == indexData.Lookup");
                                    Debug.Assert(writtenData.Lenght == indexData.Lenght, "writtenData.Lenght == indexData.Lenght");
                                }
                                else {
                                    dataStream.Seek(0, SeekOrigin.End);
                                    IndexData writtenData = Art.WriteTile(dataStream, pair.Value);
                                    indexFile.Set(pair.Key, writtenData, true);
                                }
                            }
                            else {
                                // Run, will be saved to end of data stream
                                dataStream.Seek(0, SeekOrigin.End);
                                IndexData writtenData = Art.WriteRun(dataStream, pair.Value);
                                indexFile.Set(pair.Key, writtenData, true);
                            }
                        }

                        dataStream.Flush();
                        Trace.WriteLine(String.Format("Art: File \"{0}\" succesfully updated.", mulFile), "MulLib");

                        indexFile.Save(indexStream);
                        Trace.WriteLine(String.Format("IndexFile: File \"{0}\" succesfully saved.", idxFile), "MulLib");

                        changeList.Clear();
                    }
                    else {
                        // Target data file differs from source file. Optimization will be performed.
                        try {
                            Stream dataStream = File.Open(mulFile, FileMode.Create, FileAccess.Write, FileShare.None);
                            IndexFile newIndexFile = new IndexFile();

                            for (int i = 0; i < indexFile.Count; i++) {
                                if (changeList.ContainsKey(i)) {
                                    IndexData writtenData;

                                    if (i < 16384)
                                        writtenData = Art.WriteTile(dataStream, changeList[i]);
                                    else
                                        writtenData = Art.WriteRun(dataStream, changeList[i]);

                                    newIndexFile.Set(i, writtenData, true);
                                }
                                else {
                                    IndexData indexData = indexFile.Get(i, false);
                                    if (indexData.IsValid) {
                                        byte[] data = new byte[indexData.Lenght];

                                        this.dataStream.Seek(indexData.Lookup, SeekOrigin.Begin);
                                        this.dataStream.Read(data, 0, (int)indexData.Lenght);

                                        IndexData writtenData = new IndexData();
                                        writtenData.Lookup = (uint)dataStream.Position;
                                        writtenData.Lenght = indexData.Lenght;
                                        writtenData.Extra = indexData.Extra;

                                        dataStream.Write(data, 0, (int)writtenData.Lenght);
                                    }
                                }
                            }

                            dataStream.Flush();
                            Trace.WriteLine(String.Format("Art: File \"{0}\" succesfully saved.", mulFile), "MulLib");

                            newIndexFile.Save(indexStream);
                            Trace.WriteLine(String.Format("IndexFile: File \"{0}\" succesfully saved.", idxFile), "MulLib");
                        }
                        finally {
                            if (dataStream != null)
                                dataStream.Close();
                        }
                    }
                }
                catch (Exception e) {
                    throw new Exception("Error saving Art.", e);
                }
                finally {
                    if (indexStream != null)
                        indexStream.Close();
                }
            }
        }
Пример #10
0
        /// <summary>
        /// Sets data at specified index.
        /// </summary>
        /// <param name="index">Index of data.</param>
        /// <param name="data">New data.</param>
        /// <param name="create">If true list is automaticly resized; otherwise exception is thrown.</param>
        /// <exception cref="System.ArgumentOutOfRangeException">Thrown when create is false and index is less than zero or equal to or greater than Count.</exception>
        /// <exception cref="System.ObjectDisposedException">Object has been disposed.</exception>
        public void Set(int index, IndexData data, bool create)
        {
            if (Disposed)
                throw new ObjectDisposedException("IndexFile");

            if (index > list.Count && create)
            {
                Resize(index);
            }

            list[index] = data;
        }
Пример #11
0
        /// <summary>
        /// Adds data to the end of the list.
        /// </summary>
        /// <param name="data">New data.</param>
        /// <returns>Index of written data.</returns>
        /// <exception cref="System.ObjectDisposedException">Object has been disposed.</exception>
        public int Add(IndexData data)
        {
            if (Disposed)
                throw new ObjectDisposedException("IndexFile");

            list.Add(data);

            return list.Count - 1;
        }
Пример #12
0
        /// <summary>
        /// Loads IndexFile object from file.
        /// </summary>
        /// <param name="file">File path.</param>
        public static IndexFile Load(string file)
        {
            Stream stream = null;
            BinaryReader reader = null;

            try
            {
                stream = File.OpenRead(file);
                reader = new BinaryReader(stream);

                Trace.WriteLineIf((stream.Length % IndexData.Size) != 0, "IndexFile: File size is not multiple of 12.", "MulLib");

                IndexFile indexFile = new IndexFile();

                IndexData data = new IndexData();
                for (int i = 0; i < stream.Length / IndexData.Size; i++)
                {
                    data.Lookup = reader.ReadUInt32();
                    data.Lenght = reader.ReadUInt32();
                    data.Extra = reader.ReadUInt32();

                    indexFile.list.Add(data);
                }

                Trace.WriteLine(String.Format("IndexFile: File \"{0}\" succesfully loaded.", file), "MulLib");
                return indexFile;
            }
            catch (Exception e)
            {
                throw new Exception("Error loading IndexFile.", e);
            }
            finally
            {
                if (reader != null)
                    reader.Close();

                if (stream != null)
                    stream.Close();
            }
        }
Пример #13
0
        /// <summary>
        /// Writes a run-compressed bitmap into specified file and returns structure with indexing information.
        /// </summary>
        /// <param name="stream">Stream where to write to.</param>
        /// <param name="bitmap">Bitmap to write. If null, returns invalid IndexData.</param>
        /// <returns>IndexData structure with indexing information.</returns>
        public static IndexData WriteRun(Stream stream, Bitmap bitmap)
        {
            if (stream == null)
            {
                throw new ArgumentNullException("stream");
            }

            if (bitmap == null)
            {
                return(IndexData.Empty);
            }

            BinaryWriter writer = new BinaryWriter(stream);

            IndexData indexdata = IndexData.Empty;

            indexdata.Lookup = (uint)writer.BaseStream.Position;
            indexdata.Extra  = 0;

            short width  = (short)bitmap.Width;
            short height = (short)bitmap.Height;

            writer.Write((int)0); // header, unknown
            writer.Write(width);
            writer.Write(height);

            long lookupTable = writer.BaseStream.Position;
            int  dataStart   = (int)writer.BaseStream.Position + height * 2;

            // Skip lookup table
            if (writer.BaseStream.Length < dataStart)
            {
                writer.BaseStream.SetLength(dataStart);
            }
            writer.Seek(dataStart, SeekOrigin.Begin);

            short y = 0;

            while (y < height)
            {
                // Write record to lookup table
                int pos = (int)writer.BaseStream.Position;

                writer.Seek((int)lookupTable, SeekOrigin.Begin);
                writer.Write((short)((pos - dataStart) / 2));
                lookupTable = writer.BaseStream.Position;

                writer.Seek(pos, SeekOrigin.Begin);

                // Write line
                int x = 0;
                while (x < width)
                {
                    short xOffset = 0;
                    short xRun    = 0;

                    // Skip invisible pixels
                    while (x < width && bitmap.GetPixel(x, y).A == 0)
                    {
                        xOffset++;
                        x++;
                    }

                    if (x == width)
                    {
                        break;
                    }

                    // Read list
                    int xPos = x;
                    while (xPos < width && bitmap.GetPixel(xPos, y).A != 0)
                    {
                        xPos++;
                        xRun++;
                    }

                    // Write chunk header
                    writer.Write(xOffset);
                    writer.Write(xRun);

                    // Write pixel list
                    while (x < width && bitmap.GetPixel(x, y).A != 0)
                    {
                        writer.Write(UOColorConverter.FromColor(bitmap.GetPixel(x, y)));
                        x++;
                    }
                }

                // End line
                writer.Write((short)0);
                writer.Write((short)0);

                y++;
            }

            indexdata.Lenght = (uint)writer.BaseStream.Position - indexdata.Lookup;

            return(indexdata);
        }
Пример #14
0
        /// <summary>
        /// Saves object to specified files.
        /// </summary>
        /// <param name="idxFile">Index file path.</param>
        /// <param name="mulFile">Data file path.</param>
        /// <remarks>
        /// If mulFile differs from currently loaded file, new file is optimized (data file is sorted and without empty entries).
        /// Otherwise file must be loaded with write access.
        /// </remarks>
        public void Save(string idxFile, string mulFile)
        {
            lock (syncRoot) {
                if (Disposed)
                {
                    throw new ObjectDisposedException("Art");
                }

                Stream indexStream = null;

                try {
                    indexStream = File.Open(idxFile, FileMode.Create, FileAccess.Write, FileShare.None);

                    if (String.Compare(mulFile, this.mulFile, StringComparison.InvariantCultureIgnoreCase) == 0)
                    {
                        // Target data file is same as source file. File will not be optimized.
                        Stream dataStream = this.dataStream;

                        if (!dataStream.CanWrite)
                        {
                            throw new InvalidOperationException("Trying to save data to source file, that is not opened for Write access.");
                        }

                        foreach (KeyValuePair <int, Bitmap> pair in changeList)
                        {
                            if (pair.Key < 16384)
                            {
                                // Tile, can be saved to same location in data stream
                                IndexData indexData = indexFile.Get(pair.Key, true);
                                if (indexData.IsValid)
                                {
                                    dataStream.Seek(indexData.Lookup, SeekOrigin.Begin);
                                    IndexData writtenData = Art.WriteTile(dataStream, pair.Value);

                                    Debug.Assert(writtenData.Lookup == indexData.Lookup, "writtenData.Lookup == indexData.Lookup");
                                    Debug.Assert(writtenData.Lenght == indexData.Lenght, "writtenData.Lenght == indexData.Lenght");
                                }
                                else
                                {
                                    dataStream.Seek(0, SeekOrigin.End);
                                    IndexData writtenData = Art.WriteTile(dataStream, pair.Value);
                                    indexFile.Set(pair.Key, writtenData, true);
                                }
                            }
                            else
                            {
                                // Run, will be saved to end of data stream
                                dataStream.Seek(0, SeekOrigin.End);
                                IndexData writtenData = Art.WriteRun(dataStream, pair.Value);
                                indexFile.Set(pair.Key, writtenData, true);
                            }
                        }

                        dataStream.Flush();
                        Trace.WriteLine(String.Format("Art: File \"{0}\" succesfully updated.", mulFile), "MulLib");

                        indexFile.Save(indexStream);
                        Trace.WriteLine(String.Format("IndexFile: File \"{0}\" succesfully saved.", idxFile), "MulLib");

                        changeList.Clear();
                    }
                    else
                    {
                        // Target data file differs from source file. Optimization will be performed.
                        try {
                            Stream    dataStream   = File.Open(mulFile, FileMode.Create, FileAccess.Write, FileShare.None);
                            IndexFile newIndexFile = new IndexFile();

                            for (int i = 0; i < indexFile.Count; i++)
                            {
                                if (changeList.ContainsKey(i))
                                {
                                    IndexData writtenData;

                                    if (i < 16384)
                                    {
                                        writtenData = Art.WriteTile(dataStream, changeList[i]);
                                    }
                                    else
                                    {
                                        writtenData = Art.WriteRun(dataStream, changeList[i]);
                                    }

                                    newIndexFile.Set(i, writtenData, true);
                                }
                                else
                                {
                                    IndexData indexData = indexFile.Get(i, false);
                                    if (indexData.IsValid)
                                    {
                                        byte[] data = new byte[indexData.Lenght];

                                        this.dataStream.Seek(indexData.Lookup, SeekOrigin.Begin);
                                        this.dataStream.Read(data, 0, (int)indexData.Lenght);

                                        IndexData writtenData = new IndexData();
                                        writtenData.Lookup = (uint)dataStream.Position;
                                        writtenData.Lenght = indexData.Lenght;
                                        writtenData.Extra  = indexData.Extra;

                                        dataStream.Write(data, 0, (int)writtenData.Lenght);
                                    }
                                }
                            }

                            dataStream.Flush();
                            Trace.WriteLine(String.Format("Art: File \"{0}\" succesfully saved.", mulFile), "MulLib");

                            newIndexFile.Save(indexStream);
                            Trace.WriteLine(String.Format("IndexFile: File \"{0}\" succesfully saved.", idxFile), "MulLib");
                        }
                        finally {
                            if (dataStream != null)
                            {
                                dataStream.Close();
                            }
                        }
                    }
                }
                catch (Exception e) {
                    throw new Exception("Error saving Art.", e);
                }
                finally {
                    if (indexStream != null)
                    {
                        indexStream.Close();
                    }
                }
            }
        }
Пример #15
0
 protected override Bitmap ReadFromStream(IndexData indexData)
 {
     art.dataStream.Seek(indexData.Lookup, SeekOrigin.Begin);
     return(Art.ReadRun(art.dataStream));
 }
Пример #16
0
 protected abstract Bitmap ReadFromStream(IndexData indexData);