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