@@ -12,25 +12,22 @@ namespace OpenRA.FileFormats
|
||||
{
|
||||
public static class Format2
|
||||
{
|
||||
public static int DecodeInto(byte[] src, byte[] dest)
|
||||
public static void DecodeInto(byte[] src, byte[] dest, int destIndex)
|
||||
{
|
||||
FastByteReader r = new FastByteReader(src);
|
||||
var r = new FastByteReader(src);
|
||||
|
||||
int i = 0;
|
||||
while (!r.Done())
|
||||
{
|
||||
byte cmd = r.ReadByte();
|
||||
var cmd = r.ReadByte();
|
||||
if (cmd == 0)
|
||||
{
|
||||
byte count = r.ReadByte();
|
||||
var count = r.ReadByte();
|
||||
while (count-- > 0)
|
||||
dest[i++] = 0;
|
||||
dest[destIndex++] = 0;
|
||||
}
|
||||
else
|
||||
dest[i++] = cmd;
|
||||
dest[destIndex++] = cmd;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#region Copyright & License Information
|
||||
/*
|
||||
* Copyright 2007-2011 The OpenRA Developers (see AUTHORS)
|
||||
* Copyright 2007-2013 The OpenRA Developers (see AUTHORS)
|
||||
* This file is part of OpenRA, which is free software. It is made
|
||||
* available to you under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation. For more information,
|
||||
@@ -27,7 +27,7 @@ namespace OpenRA.FileFormats
|
||||
public byte ReadByte() { return src[offset++]; }
|
||||
public int ReadWord()
|
||||
{
|
||||
int x = ReadByte();
|
||||
var x = ReadByte();
|
||||
return x | (ReadByte() << 8);
|
||||
}
|
||||
|
||||
@@ -42,84 +42,84 @@ namespace OpenRA.FileFormats
|
||||
|
||||
public static class Format80
|
||||
{
|
||||
static void ReplicatePrevious( byte[] dest, int destIndex, int srcIndex, int count )
|
||||
static void ReplicatePrevious(byte[] dest, int destIndex, int srcIndex, int count)
|
||||
{
|
||||
if( srcIndex > destIndex )
|
||||
if (srcIndex > destIndex)
|
||||
throw new NotImplementedException("srcIndex > destIndex {0} {1}".F(srcIndex, destIndex));
|
||||
|
||||
if( destIndex - srcIndex == 1 )
|
||||
if (destIndex - srcIndex == 1)
|
||||
{
|
||||
for( int i = 0 ; i < count ; i++ )
|
||||
dest[ destIndex + i ] = dest[ destIndex - 1 ];
|
||||
for (var i = 0; i < count; i++)
|
||||
dest[destIndex + i] = dest[destIndex - 1];
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int i = 0 ; i < count ; i++ )
|
||||
dest[ destIndex + i ] = dest[ srcIndex + i ];
|
||||
for (var i = 0; i < count; i++)
|
||||
dest[destIndex + i] = dest[srcIndex + i];
|
||||
}
|
||||
}
|
||||
|
||||
public static int DecodeInto( byte[] src, byte[] dest )
|
||||
public static int DecodeInto(byte[] src, byte[] dest)
|
||||
{
|
||||
var ctx = new FastByteReader(src);
|
||||
int destIndex = 0;
|
||||
var destIndex = 0;
|
||||
|
||||
while( true )
|
||||
while (true)
|
||||
{
|
||||
byte i = ctx.ReadByte();
|
||||
if( ( i & 0x80 ) == 0 )
|
||||
var i = ctx.ReadByte();
|
||||
if ((i & 0x80) == 0)
|
||||
{
|
||||
// case 2
|
||||
byte secondByte = ctx.ReadByte();
|
||||
int count = ( ( i & 0x70 ) >> 4 ) + 3;
|
||||
int rpos = ( ( i & 0xf ) << 8 ) + secondByte;
|
||||
var secondByte = ctx.ReadByte();
|
||||
var count = ((i & 0x70) >> 4) + 3;
|
||||
var rpos = ((i & 0xf) << 8) + secondByte;
|
||||
|
||||
ReplicatePrevious( dest, destIndex, destIndex - rpos, count );
|
||||
ReplicatePrevious(dest, destIndex, destIndex - rpos, count);
|
||||
destIndex += count;
|
||||
}
|
||||
else if( ( i & 0x40 ) == 0 )
|
||||
else if ((i & 0x40) == 0)
|
||||
{
|
||||
// case 1
|
||||
int count = i & 0x3F;
|
||||
if( count == 0 )
|
||||
var count = i & 0x3F;
|
||||
if (count == 0)
|
||||
return destIndex;
|
||||
|
||||
ctx.CopyTo( dest, destIndex, count );
|
||||
ctx.CopyTo(dest, destIndex, count);
|
||||
destIndex += count;
|
||||
}
|
||||
else
|
||||
{
|
||||
int count3 = i & 0x3F;
|
||||
if( count3 == 0x3E )
|
||||
var count3 = i & 0x3F;
|
||||
if (count3 == 0x3E)
|
||||
{
|
||||
// case 4
|
||||
int count = ctx.ReadWord();
|
||||
byte color = ctx.ReadByte();
|
||||
var count = ctx.ReadWord();
|
||||
var color = ctx.ReadByte();
|
||||
|
||||
for( int end = destIndex + count ; destIndex < end ; destIndex++ )
|
||||
dest[ destIndex ] = color;
|
||||
for (var end = destIndex + count; destIndex < end; destIndex++)
|
||||
dest[destIndex] = color;
|
||||
}
|
||||
else if( count3 == 0x3F )
|
||||
else if (count3 == 0x3F)
|
||||
{
|
||||
// case 5
|
||||
int count = ctx.ReadWord();
|
||||
int srcIndex = ctx.ReadWord();
|
||||
if( srcIndex >= destIndex )
|
||||
var count = ctx.ReadWord();
|
||||
var srcIndex = ctx.ReadWord();
|
||||
if (srcIndex >= destIndex)
|
||||
throw new NotImplementedException("srcIndex >= destIndex {0} {1}".F(srcIndex, destIndex));
|
||||
|
||||
for( int end = destIndex + count ; destIndex < end ; destIndex++ )
|
||||
dest[ destIndex ] = dest[ srcIndex++ ];
|
||||
for (var end = destIndex + count; destIndex < end; destIndex++)
|
||||
dest[destIndex] = dest[srcIndex++];
|
||||
}
|
||||
else
|
||||
{
|
||||
// case 3
|
||||
int count = count3 + 3;
|
||||
int srcIndex = ctx.ReadWord();
|
||||
if( srcIndex >= destIndex )
|
||||
var count = count3 + 3;
|
||||
var srcIndex = ctx.ReadWord();
|
||||
if (srcIndex >= destIndex)
|
||||
throw new NotImplementedException("srcIndex >= destIndex {0} {1}".F(srcIndex, destIndex));
|
||||
|
||||
for( int end = destIndex + count ; destIndex < end ; destIndex++ )
|
||||
dest[ destIndex ] = dest[ srcIndex++ ];
|
||||
for (var end = destIndex + count; destIndex < end; destIndex++)
|
||||
dest[destIndex] = dest[srcIndex++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
*/
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
@@ -16,13 +17,11 @@ using System.Linq;
|
||||
|
||||
namespace OpenRA.FileFormats
|
||||
{
|
||||
enum Dune2ImageFlags : int
|
||||
[Flags] enum FormatFlags : int
|
||||
{
|
||||
F80_F2 = 0,
|
||||
F2 = 2,
|
||||
L16_F80_F2_1 = 1,
|
||||
L16_F80_F2_2 = 3,
|
||||
Ln_F80_F2 = 5
|
||||
PaletteTable = 1,
|
||||
SkipFormat80 = 2,
|
||||
VariableLengthTable = 4
|
||||
}
|
||||
|
||||
class Frame : ISpriteFrame
|
||||
@@ -34,24 +33,25 @@ namespace OpenRA.FileFormats
|
||||
|
||||
public Frame(Stream s)
|
||||
{
|
||||
var flags = (Dune2ImageFlags)s.ReadUInt16();
|
||||
var flags = (FormatFlags)s.ReadUInt16();
|
||||
s.Position += 1;
|
||||
var width = s.ReadUInt16();
|
||||
var height = s.ReadUInt8();
|
||||
Size = new Size(width, height);
|
||||
|
||||
var frameSize = s.ReadUInt16();
|
||||
// Subtract header size
|
||||
var dataLeft = s.ReadUInt16() - 10;
|
||||
var dataSize = s.ReadUInt16();
|
||||
|
||||
byte[] table;
|
||||
if (flags == Dune2ImageFlags.L16_F80_F2_1 ||
|
||||
flags == Dune2ImageFlags.L16_F80_F2_2 ||
|
||||
flags == Dune2ImageFlags.Ln_F80_F2)
|
||||
if ((flags & FormatFlags.PaletteTable) != 0)
|
||||
{
|
||||
var n = flags == Dune2ImageFlags.Ln_F80_F2 ? s.ReadUInt8() : (byte)16;
|
||||
var n = (flags & FormatFlags.VariableLengthTable) != 0 ? s.ReadUInt8() : (byte)16;
|
||||
table = new byte[n];
|
||||
for (var i = 0; i < n; i++)
|
||||
table[i] = s.ReadUInt8();
|
||||
|
||||
dataLeft -= n;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -64,19 +64,18 @@ namespace OpenRA.FileFormats
|
||||
table[4] = 0x7c;
|
||||
}
|
||||
|
||||
// Subtract header size
|
||||
var imgData = s.ReadBytes(frameSize - 10);
|
||||
Data = new byte[width * height];
|
||||
|
||||
// Decode image data
|
||||
if (flags != Dune2ImageFlags.F2)
|
||||
var compressed = s.ReadBytes(dataLeft);
|
||||
if ((flags & FormatFlags.SkipFormat80) == 0)
|
||||
{
|
||||
var tempData = new byte[dataSize];
|
||||
Format80.DecodeInto(imgData, tempData);
|
||||
Format2.DecodeInto(tempData, Data);
|
||||
var temp = new byte[dataSize];
|
||||
Format80.DecodeInto(compressed, temp);
|
||||
compressed = temp;
|
||||
}
|
||||
else
|
||||
Format2.DecodeInto(imgData, Data);
|
||||
|
||||
Format2.DecodeInto(compressed, Data, 0);
|
||||
|
||||
// Lookup values in lookup table
|
||||
for (var j = 0; j < Data.Length; j++)
|
||||
|
||||
@@ -108,6 +108,10 @@ namespace OpenRA.FileFormats
|
||||
|
||||
void Decompress(Stream stream, ImageHeader h)
|
||||
{
|
||||
// No extra work is required for empty frames
|
||||
if (h.Size.Width == 0 || h.Size.Height == 0)
|
||||
return;
|
||||
|
||||
if (recurseDepth > imageCount)
|
||||
throw new InvalidDataException("Format20/40 headers contain infinite loop");
|
||||
|
||||
|
||||
@@ -89,21 +89,8 @@ namespace OpenRA.FileFormats
|
||||
|
||||
for (var j = 0; j < f.Size.Height; j++)
|
||||
{
|
||||
var k = j * f.Size.Width;
|
||||
var length = stream.ReadUInt16() - 2;
|
||||
while (length > 0)
|
||||
{
|
||||
var b = stream.ReadUInt8();
|
||||
length--;
|
||||
|
||||
if (b == 0)
|
||||
{
|
||||
k += stream.ReadUInt8();
|
||||
length--;
|
||||
}
|
||||
else
|
||||
f.Data[k++] = b;
|
||||
}
|
||||
Format2.DecodeInto(stream.ReadBytes(length), f.Data, j * f.Size.Width);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user