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:
@@ -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++];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user