mirror of
https://github.com/crskycode/GARbro.git
synced 2024-12-24 03:44:13 +08:00
Marble engine resources implementation.
This commit is contained in:
parent
e95cec0f3c
commit
26905015c2
94
ArcFormats/ArcMBL.cs
Normal file
94
ArcFormats/ArcMBL.cs
Normal file
@ -0,0 +1,94 @@
|
||||
//! \file ArcMBL.cs
|
||||
//! \date Fri Mar 27 23:11:19 2015
|
||||
//! \brief Marble Engine archive implementation.
|
||||
//
|
||||
// Copyright (C) 2015 by morkt
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using GameRes.Utility;
|
||||
|
||||
namespace GameRes.Formats.Marble
|
||||
{
|
||||
[Export(typeof(ArchiveFormat))]
|
||||
public class MblOpener : ArchiveFormat
|
||||
{
|
||||
public override string Tag { get { return "MBL"; } }
|
||||
public override string Description { get { return "Marble engine resource archive"; } }
|
||||
public override uint Signature { get { return 0; } }
|
||||
public override bool IsHierarchic { get { return false; } }
|
||||
public override bool CanCreate { get { return false; } }
|
||||
|
||||
public override ArcFile TryOpen (ArcView file)
|
||||
{
|
||||
int count = file.View.ReadInt32 (0);
|
||||
if (count <= 0 || count > 0xfffff)
|
||||
return null;
|
||||
ArcFile arc = null;
|
||||
uint filename_len = file.View.ReadUInt32 (4);
|
||||
if (filename_len > 0 && filename_len <= 0xff)
|
||||
arc = ReadIndex (file, count, filename_len, 8);
|
||||
if (null == arc)
|
||||
arc = ReadIndex (file, count, 0x10, 4);
|
||||
return arc;
|
||||
}
|
||||
|
||||
private ArcFile ReadIndex (ArcView file, int count, uint filename_len, uint index_offset)
|
||||
{
|
||||
uint index_size = (8u + filename_len) * (uint)count;
|
||||
if (index_size > file.View.Reserve (index_offset, index_size))
|
||||
return null;
|
||||
var dir = new List<Entry> (count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
string name = file.View.ReadString (index_offset, filename_len);
|
||||
if (name.Length+1 < filename_len)
|
||||
{
|
||||
uint ext_length = (uint)Math.Min (filename_len-name.Length-1, 3);
|
||||
string ext = file.View.ReadString (index_offset+name.Length+1, ext_length);
|
||||
if (!string.IsNullOrEmpty (ext))
|
||||
{
|
||||
if ("OG" == ext || "O" == ext)
|
||||
ext = "OGG";
|
||||
else if ("PR" == ext || "P" == ext)
|
||||
ext = "PRS";
|
||||
else if ("WA" == ext || "W" == ext)
|
||||
ext = "WAY";
|
||||
name = Path.ChangeExtension (name, ext);
|
||||
}
|
||||
}
|
||||
name = name.ToLowerInvariant();
|
||||
var entry = FormatCatalog.Instance.CreateEntry (name);
|
||||
index_offset += (uint)filename_len;
|
||||
entry.Offset = file.View.ReadUInt32 (index_offset);
|
||||
entry.Size = file.View.ReadUInt32 (index_offset+4);
|
||||
if (!entry.CheckPlacement (file.MaxOffset))
|
||||
return null;
|
||||
dir.Add (entry);
|
||||
index_offset += 8;
|
||||
}
|
||||
return new ArcFile (file, this, dir);
|
||||
}
|
||||
}
|
||||
}
|
227
ArcFormats/AudioWADY.cs
Normal file
227
ArcFormats/AudioWADY.cs
Normal file
@ -0,0 +1,227 @@
|
||||
//! \file AudioWADY.cs
|
||||
//! \date Sat Mar 28 01:36:42 2015
|
||||
//! \brief Marble engine audio format.
|
||||
//
|
||||
// Copyright (C) 2015 by morkt
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
namespace GameRes.Formats.Marble
|
||||
{
|
||||
public class WadyInput : SoundInput
|
||||
{
|
||||
byte MulValue;
|
||||
|
||||
public override long Position
|
||||
{
|
||||
get { return m_input.Position; }
|
||||
set { m_input.Position = value; }
|
||||
}
|
||||
|
||||
public override bool CanSeek { get { return m_input.CanSeek; } }
|
||||
|
||||
public override int SourceBitrate
|
||||
{
|
||||
get { return (int)Format.AverageBytesPerSecond * 8; }
|
||||
}
|
||||
|
||||
public override long Seek (long offset, SeekOrigin origin)
|
||||
{
|
||||
return m_input.Seek (offset, origin);
|
||||
}
|
||||
|
||||
public override int Read (byte[] buffer, int offset, int count)
|
||||
{
|
||||
return m_input.Read (buffer, offset, count);
|
||||
}
|
||||
|
||||
public override int ReadByte ()
|
||||
{
|
||||
return m_input.ReadByte();
|
||||
}
|
||||
|
||||
public WadyInput (Stream file) : base (new MemoryStream())
|
||||
{
|
||||
using (var input = new BinaryReader (file))
|
||||
{
|
||||
input.BaseStream.Seek (5, SeekOrigin.Begin);
|
||||
MulValue = input.ReadByte();
|
||||
input.BaseStream.Seek (6, SeekOrigin.Current);
|
||||
int src_size = input.ReadInt32();
|
||||
input.BaseStream.Seek (16, SeekOrigin.Current);
|
||||
var format = new WaveFormat();
|
||||
format.FormatTag = input.ReadUInt16();
|
||||
format.Channels = input.ReadUInt16();
|
||||
format.SamplesPerSecond = input.ReadUInt32();
|
||||
format.AverageBytesPerSecond = input.ReadUInt32();
|
||||
format.BlockAlign = input.ReadUInt16();
|
||||
format.BitsPerSample = input.ReadUInt16();
|
||||
format.ExtraSize = 0;
|
||||
this.Format = format;
|
||||
int remaining = (int)(input.BaseStream.Length-input.BaseStream.Position);
|
||||
if (remaining == src_size)
|
||||
{
|
||||
(m_input as MemoryStream).Capacity = src_size * 2;
|
||||
Decode (input, src_size, m_input);
|
||||
}
|
||||
else
|
||||
Decode2 (input, m_input);
|
||||
m_input.Position = 0;
|
||||
this.PcmSize = m_input.Length;
|
||||
}
|
||||
}
|
||||
|
||||
private void Decode (BinaryReader input, int count, Stream output)
|
||||
{
|
||||
using (var buffer = new BinaryWriter (output, Encoding.ASCII, true))
|
||||
{
|
||||
ushort sampleL = 0;
|
||||
ushort sampleR = 0;
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
byte v = input.ReadByte();
|
||||
if (0 != (v & 0x80))
|
||||
sampleL = (ushort)(v << 9);
|
||||
else
|
||||
sampleL += (ushort)(MulValue * SampleTable[v]);
|
||||
buffer.Write (sampleL);
|
||||
if (1 != Format.Channels)
|
||||
{
|
||||
++i;
|
||||
v = input.ReadByte();
|
||||
if (0 != (v & 0x80))
|
||||
sampleR = (ushort)(v << 9);
|
||||
else
|
||||
sampleR += (ushort)(MulValue * SampleTable[v]);
|
||||
buffer.Write (sampleR);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void Decode2 (BinaryReader input, Stream output)
|
||||
{
|
||||
if (1 != Format.Channels)
|
||||
{
|
||||
int channel_size = input.ReadInt32();
|
||||
Decode3 (input, output, 2);
|
||||
input.BaseStream.Position = 0x38 + channel_size;
|
||||
output.Position = 2;
|
||||
Decode3 (input, output, 2);
|
||||
}
|
||||
else
|
||||
Decode3 (input, output, 0);
|
||||
}
|
||||
|
||||
private void Decode3 (BinaryReader input, Stream output, int step)
|
||||
{
|
||||
input.ReadInt32(); // unpacked_size
|
||||
int count = input.ReadInt32();
|
||||
using (var buffer = new BinaryWriter (output, Encoding.ASCII, true))
|
||||
{
|
||||
short sample = input.ReadInt16();
|
||||
buffer.Write (sample);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
if (count - 300 == i)
|
||||
sample = 0;
|
||||
ushort v = input.ReadByte();
|
||||
if (0 != (v & 1))
|
||||
{
|
||||
ushort v14 = (ushort)((v >> 1) & 0x7F);
|
||||
if (0 != (v14 & 0x40))
|
||||
sample = (short)(v14 << 10);
|
||||
else
|
||||
sample += (short)SampleTable2[v14];
|
||||
buffer.Write (sample);
|
||||
if (step != 0)
|
||||
buffer.BaseStream.Seek (step, SeekOrigin.Current);
|
||||
}
|
||||
else
|
||||
{
|
||||
v |= (ushort)(input.ReadByte() << 8);
|
||||
int repeat = SizeTable[(v >> 1) & 7];
|
||||
short end = (short)(v & 0xFFF0);
|
||||
double inc = (end - sample) / (double)repeat;
|
||||
double v8 = sample;
|
||||
for (int j = 0; j < repeat; ++j)
|
||||
{
|
||||
v8 += inc;
|
||||
buffer.Write ((short)v8);
|
||||
if (step != 0)
|
||||
buffer.BaseStream.Seek (step, SeekOrigin.Current);
|
||||
}
|
||||
sample = end;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static readonly int[] SizeTable = new int[] { 3, 4, 5, 6, 8, 0x10, 0x20, 0x100 };
|
||||
|
||||
static readonly ushort[] SampleTable = new ushort[] {
|
||||
0x0000, 0x0002, 0x0004, 0x0006, 0x0008, 0x000A, 0x000C, 0x000F,
|
||||
0x0012, 0x0015, 0x0018, 0x001C, 0x0020, 0x0024, 0x0028, 0x002C,
|
||||
0x0031, 0x0036, 0x003B, 0x0040, 0x0046, 0x004C, 0x0052, 0x0058,
|
||||
0x005F, 0x0066, 0x006D, 0x0074, 0x007C, 0x0084, 0x008C, 0x0094,
|
||||
0x00A0, 0x00AA, 0x00B4, 0x00BE, 0x00C8, 0x00D2, 0x00DC, 0x00E6,
|
||||
0x00F0, 0x00FF, 0x010E, 0x011D, 0x012C, 0x0140, 0x0154, 0x0168,
|
||||
0x017C, 0x0190, 0x01A9, 0x01C2, 0x01DB, 0x01F4, 0x020D, 0x0226,
|
||||
0x0244, 0x0262, 0x028A, 0x02BC, 0x02EE, 0x0320, 0x0384, 0x03E8,
|
||||
0x0000, 0xFFFE, 0xFFFC, 0xFFFA, 0xFFF8, 0xFFF6, 0xFFF4, 0xFFF1,
|
||||
0xFFEE, 0xFFEB, 0xFFE8, 0xFFE4, 0xFFE0, 0xFFDC, 0xFFD8, 0xFFD4,
|
||||
0xFFCF, 0xFFCA, 0xFFC5, 0xFFC0, 0xFFBA, 0xFFB4, 0xFFAE, 0xFFA8,
|
||||
0xFFA1, 0xFF9A, 0xFF93, 0xFF8C, 0xFF84, 0xFF7C, 0xFF74, 0xFF6C,
|
||||
0xFF60, 0xFF56, 0xFF4C, 0xFF42, 0xFF38, 0xFF2E, 0xFF24, 0xFF1A,
|
||||
0xFF10, 0xFF01, 0xFEF2, 0xFEE3, 0xFED4, 0xFEC0, 0xFEAC, 0xFE98,
|
||||
0xFE84, 0xFE70, 0xFE57, 0xFE3E, 0xFE25, 0xFE0C, 0xFDF3, 0xFDDA,
|
||||
0xFDBC, 0xFD9E, 0xFD76, 0xFD44, 0xFD12, 0xFCE0, 0xFC7C, 0xFC18,
|
||||
};
|
||||
|
||||
static readonly ushort[] SampleTable2 = new ushort[] {
|
||||
0x0000, 0x0004, 0x0008, 0x000C, 0x0013, 0x0018, 0x001E, 0x0026,
|
||||
0x002F, 0x003B, 0x004A, 0x005C, 0x0073, 0x0090, 0x00B4, 0x00E1,
|
||||
0x0119, 0x0160, 0x01B8, 0x0226, 0x02AF, 0x035B, 0x0431, 0x053E,
|
||||
0x068E, 0x0831, 0x0A3D, 0x0CCD, 0x1000, 0x1400, 0x1900, 0x1F40,
|
||||
0x0000, 0xFFFC, 0xFFF8, 0xFFF4, 0xFFED, 0xFFE8, 0xFFE2, 0xFFDA,
|
||||
0xFFD1, 0xFFC5, 0xFFB6, 0xFFA4, 0xFF8D, 0xFF70, 0xFF4C, 0xFF1F,
|
||||
0xFEE7, 0xFEA0, 0xFE48, 0xFDDA, 0xFD51, 0xFCA5, 0xFBCF, 0xFAC2,
|
||||
0xF972, 0xF7CF, 0xF5C3, 0xF333, 0xF000, 0xEC00, 0xE700, 0xE0C0,
|
||||
};
|
||||
}
|
||||
|
||||
[Export(typeof(AudioFormat))]
|
||||
public class WadyAudio : AudioFormat
|
||||
{
|
||||
public override string Tag { get { return "WAY"; } }
|
||||
public override string Description { get { return "Marble engine wave audio format"; } }
|
||||
public override uint Signature { get { return 0x59444157u; } } // 'WADY'
|
||||
|
||||
public override SoundInput TryOpen (Stream file)
|
||||
{
|
||||
return new WadyInput (file);
|
||||
}
|
||||
}
|
||||
}
|
221
ArcFormats/ImagePRS.cs
Normal file
221
ArcFormats/ImagePRS.cs
Normal file
@ -0,0 +1,221 @@
|
||||
//! \file ImagePRS.cs
|
||||
//! \date Sat Mar 28 00:15:43 2015
|
||||
//! \brief Marble engine image format.
|
||||
//
|
||||
// Copyright (C) 2015 by morkt
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to
|
||||
// deal in the Software without restriction, including without limitation the
|
||||
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||
// sell copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
// IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.Composition;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using GameRes.Utility;
|
||||
|
||||
namespace GameRes.Formats.Marble
|
||||
{
|
||||
internal class PrsMetaData : ImageMetaData
|
||||
{
|
||||
public byte Flag;
|
||||
public uint PackedSize;
|
||||
}
|
||||
|
||||
[Export(typeof(ImageFormat))]
|
||||
public class PrsFormat : ImageFormat
|
||||
{
|
||||
public override string Tag { get { return "PRS"; } }
|
||||
public override string Description { get { return "Marble engine image format"; } }
|
||||
public override uint Signature { get { return 0; } }
|
||||
|
||||
public override void Write (Stream file, ImageData image)
|
||||
{
|
||||
throw new NotImplementedException ("PrsFormat.Write not implemented");
|
||||
}
|
||||
|
||||
public override ImageMetaData ReadMetaData (Stream stream)
|
||||
{
|
||||
var header = new byte[0x10];
|
||||
if (header.Length != stream.Read (header, 0, header.Length))
|
||||
return null;
|
||||
if (header[0] != 'Y' || header[1] != 'B' || header[3] != 3)
|
||||
return null;
|
||||
|
||||
return new PrsMetaData
|
||||
{
|
||||
Width = LittleEndian.ToUInt16 (header, 12),
|
||||
Height = LittleEndian.ToUInt16 (header, 14),
|
||||
BPP = 24,
|
||||
Flag = header[2],
|
||||
PackedSize = LittleEndian.ToUInt32 (header, 4),
|
||||
};
|
||||
}
|
||||
|
||||
public override ImageData Read (Stream stream, ImageMetaData info)
|
||||
{
|
||||
var meta = info as PrsMetaData;
|
||||
if (null == meta)
|
||||
throw new ArgumentException ("PrsFormat.Read should be supplied with PrsMetaData", "info");
|
||||
|
||||
stream.Position = 0x10;
|
||||
using (var reader = new Reader (stream, meta))
|
||||
{
|
||||
reader.Unpack();
|
||||
byte[] pixels = reader.Data;
|
||||
var bitmap = BitmapSource.Create ((int)meta.Width, (int)meta.Height, 96, 96,
|
||||
PixelFormats.Bgr24, null, pixels, (int)meta.Width*3);
|
||||
bitmap.Freeze();
|
||||
return new ImageData (bitmap, meta);
|
||||
}
|
||||
}
|
||||
|
||||
internal class Reader : IDisposable
|
||||
{
|
||||
BinaryReader m_input;
|
||||
byte[] m_output;
|
||||
uint m_size;
|
||||
byte m_flag;
|
||||
|
||||
public byte[] Data { get { return m_output; } }
|
||||
|
||||
public Reader (Stream file, PrsMetaData info)
|
||||
{
|
||||
m_input = new BinaryReader (file, Encoding.ASCII, true);
|
||||
m_output = new byte[info.Width*info.Height*3];
|
||||
m_size = info.PackedSize;
|
||||
m_flag = info.Flag;
|
||||
}
|
||||
|
||||
static readonly int[] LengthTable = InitLengthTable();
|
||||
|
||||
private static int[] InitLengthTable ()
|
||||
{
|
||||
var length_table = new int[256];
|
||||
for (int i = 0; i < 0xfe; ++i)
|
||||
length_table[i] = i + 3;
|
||||
length_table[0xfe] = 0x400;
|
||||
length_table[0xff] = 0x1000;
|
||||
return length_table;
|
||||
}
|
||||
|
||||
public void Unpack ()
|
||||
{
|
||||
int dst = 0;
|
||||
int remaining = (int)m_size;
|
||||
int bit = 0;
|
||||
int ctl = 0;
|
||||
while (remaining > 0 && dst < m_output.Length)
|
||||
{
|
||||
bit >>= 1;
|
||||
if (0 == bit)
|
||||
{
|
||||
ctl = m_input.ReadByte();
|
||||
--remaining;
|
||||
bit = 0x80;
|
||||
}
|
||||
if (0 == (ctl & bit))
|
||||
{
|
||||
m_output[dst++] = m_input.ReadByte();
|
||||
--remaining;
|
||||
continue;
|
||||
}
|
||||
int b = m_input.ReadByte();
|
||||
--remaining;
|
||||
int length = 0;
|
||||
int shift = 0;
|
||||
|
||||
if (0 != (b & 0x80))
|
||||
{
|
||||
if (remaining <= 0)
|
||||
break;
|
||||
shift = m_input.ReadByte();
|
||||
--remaining;
|
||||
shift |= (b & 0x3f) << 8;
|
||||
if (0 != (b & 0x40))
|
||||
{
|
||||
if (remaining <= 0)
|
||||
break;
|
||||
int offset = m_input.ReadByte();
|
||||
--remaining;
|
||||
length = LengthTable[offset];
|
||||
}
|
||||
else
|
||||
{
|
||||
length = (shift & 0xf) + 3;
|
||||
shift >>= 4;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
length = b >> 2;
|
||||
b &= 3;
|
||||
if (3 == b)
|
||||
{
|
||||
length += 9;
|
||||
int read = m_input.Read (m_output, dst, length);
|
||||
if (read < length)
|
||||
break;
|
||||
remaining -= length;
|
||||
dst += length;
|
||||
continue;
|
||||
}
|
||||
shift = length;
|
||||
length = b + 2;
|
||||
}
|
||||
++shift;
|
||||
if (dst < shift)
|
||||
throw new InvalidFormatException ("Invalid offset value");
|
||||
Binary.CopyOverlapped (m_output, dst-shift, dst, length);
|
||||
dst += length;
|
||||
}
|
||||
if (m_flag != 0)
|
||||
{
|
||||
for (int i = 3; i < m_output.Length; ++i)
|
||||
m_output[i] += m_output[i-3];
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable Members
|
||||
bool disposed = false;
|
||||
|
||||
public void Dispose ()
|
||||
{
|
||||
Dispose (true);
|
||||
GC.SuppressFinalize (this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose (bool disposing)
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
m_input.Dispose();
|
||||
}
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user