Duplicate part of LCWCompression to VqaReader

Duplicates the part needed by the VqaReader,
so we can move LCWCompression to Mods.Cnc
ahead of VQA (which has some additional prerequisites).
This commit is contained in:
reaperrr
2019-12-09 01:45:49 +01:00
committed by teinarss
parent ed618c807d
commit c687600d66

View File

@@ -330,7 +330,7 @@ namespace OpenRA.Mods.Common.FileFormats
Array.Clear(cbf, 0, cbf.Length);
Array.Clear(cbfBuffer, 0, cbfBuffer.Length);
var decodeCount = 0;
decodeCount = LCWCompression.DecodeInto(fileBuffer, cbfBuffer, decodeMode ? 1 : 0, decodeMode);
decodeCount = LCWDecodeInto(fileBuffer, cbfBuffer, decodeMode ? 1 : 0, decodeMode);
if ((videoFlags & 0x10) == 16)
{
var p = 0;
@@ -366,7 +366,7 @@ namespace OpenRA.Mods.Common.FileFormats
if (type == "CBP0")
cbf = (byte[])cbp.Clone();
else
LCWCompression.DecodeInto(cbp, cbf);
LCWDecodeInto(cbp, cbf);
chunkBufferOffset = currentChunkBuffer = 0;
}
@@ -391,7 +391,7 @@ namespace OpenRA.Mods.Common.FileFormats
// Frame data
case "VPTZ":
LCWCompression.DecodeInto(s.ReadBytes(subchunkLength), origData);
LCWDecodeInto(s.ReadBytes(subchunkLength), origData);
// This is the last subchunk
return;
@@ -399,9 +399,9 @@ namespace OpenRA.Mods.Common.FileFormats
Array.Clear(origData, 0, origData.Length);
s.ReadBytes(fileBuffer, 0, subchunkLength);
if (fileBuffer[0] != 0)
vtprSize = LCWCompression.DecodeInto(fileBuffer, origData);
vtprSize = LCWDecodeInto(fileBuffer, origData);
else
LCWCompression.DecodeInto(fileBuffer, origData, 1, true);
LCWDecodeInto(fileBuffer, origData, 1, true);
return;
case "VPTR":
Array.Clear(origData, 0, origData.Length);
@@ -529,5 +529,75 @@ namespace OpenRA.Mods.Common.FileFormats
}
}
}
// TODO: Maybe replace this with LCWCompression.DecodeInto again later
public static int LCWDecodeInto(byte[] src, byte[] dest, int srcOffset = 0, bool reverse = false)
{
var ctx = new FastByteReader(src, srcOffset);
var destIndex = 0;
while (true)
{
var i = ctx.ReadByte();
if ((i & 0x80) == 0)
{
// case 2
var secondByte = ctx.ReadByte();
var count = ((i & 0x70) >> 4) + 3;
var rpos = ((i & 0xf) << 8) + secondByte;
if (destIndex + count > dest.Length)
return destIndex;
// Replicate previous
var srcIndex = destIndex - rpos;
if (srcIndex > destIndex)
throw new NotImplementedException("srcIndex > destIndex {0} {1}".F(srcIndex, destIndex));
for (var j = 0; j < count; j++)
{
if (destIndex - srcIndex == 1)
dest[destIndex + j] = dest[destIndex - 1];
else
dest[destIndex + j] = dest[srcIndex + j];
}
destIndex += count;
}
else if ((i & 0x40) == 0)
{
// case 1
var count = i & 0x3F;
if (count == 0)
return destIndex;
ctx.CopyTo(dest, destIndex, count);
destIndex += count;
}
else
{
var count3 = i & 0x3F;
if (count3 == 0x3E)
{
// case 4
var count = ctx.ReadWord();
var color = ctx.ReadByte();
for (var end = destIndex + count; destIndex < end; destIndex++)
dest[destIndex] = color;
}
else
{
// If count3 == 0x3F it's case 5, else case 3
var count = count3 == 0x3F ? ctx.ReadWord() : count3 + 3;
var srcIndex = reverse ? destIndex - ctx.ReadWord() : ctx.ReadWord();
if (srcIndex >= destIndex)
throw new NotImplementedException("srcIndex >= destIndex {0} {1}".F(srcIndex, destIndex));
for (var end = destIndex + count; destIndex < end; destIndex++)
dest[destIndex] = dest[srcIndex++];
}
}
}
}
}
}