Rewrite ShpTSReader. Closes #3746.
This commit is contained in:
@@ -1,615 +1,113 @@
|
|||||||
#region Copyright & License Information
|
#region Copyright & License Information
|
||||||
/*
|
/*
|
||||||
* Copyright 2007-2013 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,
|
||||||
* see LICENSE.
|
* see COPYING.
|
||||||
*/
|
*/
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Collections;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
namespace OpenRA.FileFormats
|
namespace OpenRA.FileFormats
|
||||||
{
|
{
|
||||||
|
public class TSImageHeader
|
||||||
public struct Header
|
|
||||||
{
|
{
|
||||||
public ushort A;
|
public readonly Size Size;
|
||||||
// Unknown
|
public readonly float2 Offset;
|
||||||
// Width and Height of the images
|
|
||||||
public ushort Width;
|
public readonly uint FileOffset;
|
||||||
public ushort Height;
|
public readonly byte Format;
|
||||||
public ushort NumImages;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class HeaderImage
|
|
||||||
{
|
|
||||||
public ushort x;
|
|
||||||
public ushort y;
|
|
||||||
public ushort cx;
|
|
||||||
public ushort cy;
|
|
||||||
// cx and cy are width n height of stored image
|
|
||||||
public byte compression;
|
|
||||||
public byte[] align;
|
|
||||||
public byte[] transparent;
|
|
||||||
public int zero;
|
|
||||||
public int offset;
|
|
||||||
public byte[] Image;
|
public byte[] Image;
|
||||||
|
|
||||||
|
public TSImageHeader(Stream stream, Size frameSize)
|
||||||
|
{
|
||||||
|
var x = stream.ReadUInt16();
|
||||||
|
var y = stream.ReadUInt16();
|
||||||
|
var width = stream.ReadUInt16();
|
||||||
|
var height = stream.ReadUInt16();
|
||||||
|
|
||||||
|
Offset = new float2(x + 0.5f * (width - frameSize.Width), y + 0.5f * (height - frameSize.Height));
|
||||||
|
Size = new Size(width, height);
|
||||||
|
|
||||||
|
Format = stream.ReadUInt8();
|
||||||
|
stream.Position += 11;
|
||||||
|
FileOffset = stream.ReadUInt32();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct SHPData
|
public class ShpTSReader
|
||||||
{
|
|
||||||
public HeaderImage HeaderImage;
|
|
||||||
public byte[] Databuffer;
|
|
||||||
public byte[] FrameImage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public struct SHP
|
|
||||||
{
|
|
||||||
public Header Header;
|
|
||||||
public SHPData[] Data;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public class ShpTSReader : IEnumerable<HeaderImage>
|
|
||||||
{
|
{
|
||||||
public readonly int ImageCount;
|
public readonly int ImageCount;
|
||||||
public readonly ushort Width;
|
public readonly Size Size;
|
||||||
public readonly ushort Height;
|
|
||||||
public readonly ushort Width2;
|
|
||||||
public readonly ushort Height2;
|
|
||||||
public int arroff = 0;
|
|
||||||
public int erri = 0;
|
|
||||||
public int errj = 0;
|
|
||||||
public int errk = 0;
|
|
||||||
public int errl = 0;
|
|
||||||
|
|
||||||
public static int FindNextOffsetFrom(SHP SHP, int Init, int Last)
|
readonly List<TSImageHeader> frames = new List<TSImageHeader>();
|
||||||
|
public IEnumerable<TSImageHeader> Frames { get { return frames; } }
|
||||||
|
|
||||||
|
public ShpTSReader(Stream stream)
|
||||||
{
|
{
|
||||||
int result;
|
stream.ReadUInt16();
|
||||||
result = 0;
|
var width = stream.ReadUInt16();
|
||||||
Last++;
|
var height = stream.ReadUInt16();
|
||||||
while ((result == 0) && (Init < Last))
|
Size = new Size(width, height);
|
||||||
|
ImageCount = stream.ReadUInt16();
|
||||||
|
|
||||||
|
for (var i = 0; i < ImageCount; i++)
|
||||||
|
frames.Add(new TSImageHeader(stream, Size));
|
||||||
|
|
||||||
|
for (var i = 0; i < ImageCount; i++)
|
||||||
{
|
{
|
||||||
result = SHP.Data[Init].HeaderImage.offset;
|
var f = frames[i];
|
||||||
Init++;
|
if (f.FileOffset == 0)
|
||||||
}
|
continue;
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
private readonly List<HeaderImage> headers = new List<HeaderImage>();
|
stream.Position = f.FileOffset;
|
||||||
|
|
||||||
public ShpTSReader(Stream s)
|
// Uncompressed
|
||||||
{
|
if (f.Format == 1 || f.Format == 0)
|
||||||
|
f.Image = stream.ReadBytes(f.Size.Width * f.Size.Height);
|
||||||
|
|
||||||
SHP SHP = new SHP();
|
// Uncompressed scanlines
|
||||||
int FileSize;
|
else if (f.Format == 2)
|
||||||
int x;
|
|
||||||
int k = 0;
|
|
||||||
int l = 0;
|
|
||||||
|
|
||||||
int ImageSize;
|
|
||||||
int NextOffset;
|
|
||||||
|
|
||||||
byte[] FData;
|
|
||||||
byte cp;
|
|
||||||
byte[] Databuffer;
|
|
||||||
|
|
||||||
FileSize = (int)s.Length;
|
|
||||||
// Get Header
|
|
||||||
SHP.Header.A = s.ReadUInt16();
|
|
||||||
SHP.Header.Width = s.ReadUInt16();
|
|
||||||
SHP.Header.Height = s.ReadUInt16();
|
|
||||||
SHP.Header.NumImages = s.ReadUInt16();
|
|
||||||
|
|
||||||
SHP.Data = new SHPData[SHP.Header.NumImages + 1];
|
|
||||||
|
|
||||||
ImageCount = SHP.Header.NumImages;
|
|
||||||
|
|
||||||
for (x = 1; x <= SHP.Header.NumImages; x++)
|
|
||||||
{
|
{
|
||||||
SHP.Data[x].HeaderImage = new HeaderImage();
|
f.Image = new byte[f.Size.Width * f.Size.Height];
|
||||||
|
for (var j = 0; j < f.Size.Height; j++)
|
||||||
SHP.Data[x].HeaderImage.x = s.ReadUInt16();
|
|
||||||
SHP.Data[x].HeaderImage.y = s.ReadUInt16();
|
|
||||||
SHP.Data[x].HeaderImage.cx = s.ReadUInt16();
|
|
||||||
SHP.Data[x].HeaderImage.cy = s.ReadUInt16();
|
|
||||||
|
|
||||||
SHP.Data[x].HeaderImage.compression = s.ReadUInt8();
|
|
||||||
SHP.Data[x].HeaderImage.align = s.ReadBytes(3);
|
|
||||||
s.ReadInt32();
|
|
||||||
SHP.Data[x].HeaderImage.zero = s.ReadUInt8();
|
|
||||||
SHP.Data[x].HeaderImage.transparent = s.ReadBytes(3);
|
|
||||||
|
|
||||||
SHP.Data[x].HeaderImage.offset = s.ReadInt32();
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
Width = SHP.Header.Width;
|
|
||||||
Height = SHP.Header.Height;
|
|
||||||
|
|
||||||
for (int i = 0; i < ImageCount; i++)
|
|
||||||
{
|
|
||||||
headers.Add(SHP.Data[i+1].HeaderImage);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read and decode each image from the file
|
|
||||||
for (x = 1; x <= SHP.Header.NumImages; x++)
|
|
||||||
{
|
|
||||||
headers[x - 1].Image = new byte[(Width * Height)];
|
|
||||||
for (int i = 0; i < headers[x - 1].Image.Length; i++)
|
|
||||||
headers[x - 1].Image[i] = 0;
|
|
||||||
|
|
||||||
FData = new byte[(Width * Height)];
|
|
||||||
|
|
||||||
// Does it really reads the frame?
|
|
||||||
if (SHP.Data[x].HeaderImage.offset != 0)
|
|
||||||
{
|
{
|
||||||
try
|
var length = stream.ReadUInt16() - 2;
|
||||||
|
stream.Read(f.Image, f.Size.Width * j, length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// RLE-zero compressed scanlines
|
||||||
|
else if (f.Format == 3)
|
||||||
|
{
|
||||||
|
f.Image = new byte[f.Size.Width * f.Size.Height];
|
||||||
|
|
||||||
|
for (var j = 0; j < f.Size.Height; j++)
|
||||||
|
{
|
||||||
|
var k = j * f.Size.Width;
|
||||||
|
var length = stream.ReadUInt16() - 2;
|
||||||
|
while (length > 0)
|
||||||
{
|
{
|
||||||
// Now it checks the compression:
|
var b = stream.ReadUInt8();
|
||||||
if ((SHP.Data[x].HeaderImage.compression == 3))
|
length--;
|
||||||
{
|
|
||||||
// decode it
|
if (b == 0)
|
||||||
// Compression 3
|
|
||||||
NextOffset = FindNextOffsetFrom(SHP, x + 1, SHP.Header.NumImages);
|
|
||||||
if (NextOffset != 0)
|
|
||||||
{
|
{
|
||||||
|
k += stream.ReadUInt8();
|
||||||
ImageSize = NextOffset - SHP.Data[x].HeaderImage.offset;
|
length--;
|
||||||
Databuffer = new byte[ImageSize];
|
|
||||||
for (int i = 0; i < ImageSize; i++)
|
|
||||||
{
|
|
||||||
s.Seek(SHP.Data[x].HeaderImage.offset + i, SeekOrigin.Begin);
|
|
||||||
Databuffer[i] = s.ReadUInt8();
|
|
||||||
}
|
|
||||||
SHP.Data[x].Databuffer = new byte[(SHP.Data[x].HeaderImage.cx * SHP.Data[x].HeaderImage.cy)];
|
|
||||||
Decode3(Databuffer, ref SHP.Data[x].Databuffer, SHP.Data[x].HeaderImage.cx, SHP.Data[x].HeaderImage.cy, ref FileSize);
|
|
||||||
|
|
||||||
k = 0;
|
|
||||||
l = 0;
|
|
||||||
for (int i = 0; i < Height; i++)
|
|
||||||
{
|
|
||||||
erri = i;
|
|
||||||
for (int j = SHP.Data[x].HeaderImage.x; j < Width; j++)
|
|
||||||
{
|
|
||||||
errj = j;
|
|
||||||
errl = l;
|
|
||||||
errk = k;
|
|
||||||
arroff = i + j + l;
|
|
||||||
|
|
||||||
if (((j + 1) > (SHP.Data[x].HeaderImage.cx + SHP.Data[x].HeaderImage.x)) || ((i + 1) > (SHP.Data[x].HeaderImage.cy)))
|
|
||||||
cp = 0;
|
|
||||||
else
|
|
||||||
cp = SHP.Data[x].Databuffer[i + (j - SHP.Data[x].HeaderImage.x) + l];
|
|
||||||
|
|
||||||
FData[i + j + k] = cp;
|
|
||||||
|
|
||||||
if (j == (SHP.Data[x].HeaderImage.cx + SHP.Data[x].HeaderImage.x - 1))
|
|
||||||
l = l + (SHP.Data[x].HeaderImage.cx - 1);
|
|
||||||
|
|
||||||
if (j == (Width - 1))
|
|
||||||
k = k + (Width - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//FData = headers[x - 1].Image;
|
|
||||||
k = 0;
|
|
||||||
for (int i = 0; i < (Height - SHP.Data[x].HeaderImage.y); i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < Width; j++)
|
|
||||||
{
|
|
||||||
headers[x - 1].Image[i + j + k + (Width * SHP.Data[x].HeaderImage.y)] = FData[i + j + k];
|
|
||||||
if (j == (Width - 1))
|
|
||||||
{
|
|
||||||
k = k + (Width - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
f.Image[k++] = b;
|
||||||
|
|
||||||
ImageSize = 0;
|
|
||||||
ImageSize = FileSize - SHP.Data[x].HeaderImage.offset;
|
|
||||||
Databuffer = new byte[ImageSize];
|
|
||||||
for (int i = 0; i < ImageSize; i++)
|
|
||||||
{
|
|
||||||
s.Seek(SHP.Data[x].HeaderImage.offset + i, SeekOrigin.Begin);
|
|
||||||
Databuffer[i] = s.ReadUInt8();
|
|
||||||
}
|
|
||||||
SHP.Data[x].Databuffer = new byte[((SHP.Data[x].HeaderImage.cx * SHP.Data[x].HeaderImage.cy))];
|
|
||||||
|
|
||||||
Decode3(Databuffer, ref SHP.Data[x].Databuffer, SHP.Data[x].HeaderImage.cx, SHP.Data[x].HeaderImage.cy, ref ImageSize);
|
|
||||||
|
|
||||||
k = 0;
|
|
||||||
l = 0;
|
|
||||||
for (int i = 0; i < Height; i++)
|
|
||||||
{
|
|
||||||
erri = i;
|
|
||||||
for (int j = SHP.Data[x].HeaderImage.x; j < Width; j++)
|
|
||||||
{
|
|
||||||
errj = j;
|
|
||||||
errl = l;
|
|
||||||
errk = k;
|
|
||||||
arroff = i + j + l;
|
|
||||||
|
|
||||||
if (((j + 1) > (SHP.Data[x].HeaderImage.cx + SHP.Data[x].HeaderImage.x)) || ((i + 1) > (SHP.Data[x].HeaderImage.cy)))
|
|
||||||
cp = 0;
|
|
||||||
else
|
|
||||||
cp = SHP.Data[x].Databuffer[i + (j - SHP.Data[x].HeaderImage.x) + l];
|
|
||||||
|
|
||||||
FData[i + j + k] = cp;
|
|
||||||
|
|
||||||
if (j == (SHP.Data[x].HeaderImage.cx + SHP.Data[x].HeaderImage.x - 1))
|
|
||||||
l = l + (SHP.Data[x].HeaderImage.cx - 1);
|
|
||||||
|
|
||||||
if (j == (Width - 1))
|
|
||||||
k = k + (Width - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//FData = headers[x - 1].Image;
|
|
||||||
k = 0;
|
|
||||||
for (int i = 0; i < (Height - SHP.Data[x].HeaderImage.y); i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < Width; j++)
|
|
||||||
{
|
|
||||||
headers[x - 1].Image[i + j + k + (Width * SHP.Data[x].HeaderImage.y)] = FData[i + j + k];
|
|
||||||
if (j == (Width - 1))
|
|
||||||
{
|
|
||||||
k = k + (Width - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if ((SHP.Data[x].HeaderImage.compression == 2))
|
|
||||||
{
|
|
||||||
NextOffset = FindNextOffsetFrom(SHP, x + 1, SHP.Header.NumImages);
|
|
||||||
if (NextOffset != 0)
|
|
||||||
{
|
|
||||||
ImageSize = NextOffset - SHP.Data[x].HeaderImage.offset;
|
|
||||||
SHP.Data[x].Databuffer = new byte[(SHP.Data[x].HeaderImage.cx * SHP.Data[x].HeaderImage.cy)];
|
|
||||||
Databuffer = new byte[ImageSize];
|
|
||||||
for (int i = 0; i < ImageSize; i++)
|
|
||||||
{
|
|
||||||
s.Seek(SHP.Data[x].HeaderImage.offset + i, SeekOrigin.Begin);
|
|
||||||
Databuffer[i] = s.ReadUInt8();
|
|
||||||
}
|
|
||||||
|
|
||||||
Decode2(Databuffer, ref SHP.Data[x].Databuffer, SHP.Data[x].HeaderImage.cx, SHP.Data[x].HeaderImage.cy, ref ImageSize);
|
|
||||||
|
|
||||||
k = 0;
|
|
||||||
l = 0;
|
|
||||||
for (int i = 0; i < Height; i++)
|
|
||||||
{
|
|
||||||
erri = i;
|
|
||||||
for (int j = SHP.Data[x].HeaderImage.x; j < Width; j++)
|
|
||||||
{
|
|
||||||
errj = j;
|
|
||||||
errl = l;
|
|
||||||
errk = k;
|
|
||||||
arroff = i + j + l;
|
|
||||||
|
|
||||||
if (((j + 1) > (SHP.Data[x].HeaderImage.cx + SHP.Data[x].HeaderImage.x)) || ((i + 1) > (SHP.Data[x].HeaderImage.cy)))
|
|
||||||
cp = 0;
|
|
||||||
else
|
|
||||||
cp = SHP.Data[x].Databuffer[i + (j - SHP.Data[x].HeaderImage.x) + l];
|
|
||||||
|
|
||||||
FData[i + j + k] = cp;
|
|
||||||
|
|
||||||
if (j == (SHP.Data[x].HeaderImage.cx + SHP.Data[x].HeaderImage.x - 1))
|
|
||||||
l = l + (SHP.Data[x].HeaderImage.cx - 1);
|
|
||||||
|
|
||||||
if (j == (Width - 1))
|
|
||||||
k = k + (Width - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//FData = headers[x - 1].Image;
|
|
||||||
k = 0;
|
|
||||||
for (int i = 0; i < (Height - SHP.Data[x].HeaderImage.y); i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < Width; j++)
|
|
||||||
{
|
|
||||||
headers[x - 1].Image[i + j + k + (Width * SHP.Data[x].HeaderImage.y)] = FData[i + j + k];
|
|
||||||
if (j == (Width - 1))
|
|
||||||
{
|
|
||||||
k = k + (Width - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compression 2
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ImageSize = 0;
|
|
||||||
ImageSize = FileSize - SHP.Data[x].HeaderImage.offset;
|
|
||||||
Databuffer = new byte[ImageSize];
|
|
||||||
for (int i = 0; i < ImageSize; i++)
|
|
||||||
{
|
|
||||||
s.Seek(SHP.Data[x].HeaderImage.offset + i, SeekOrigin.Begin);
|
|
||||||
Databuffer[i] = s.ReadUInt8();
|
|
||||||
}
|
|
||||||
SHP.Data[x].Databuffer = new byte[((SHP.Data[x].HeaderImage.cx * SHP.Data[x].HeaderImage.cy))];
|
|
||||||
Decode2(Databuffer, ref SHP.Data[x].Databuffer, SHP.Data[x].HeaderImage.cx, SHP.Data[x].HeaderImage.cy, ref ImageSize);
|
|
||||||
|
|
||||||
k = 0;
|
|
||||||
l = 0;
|
|
||||||
for (int i = 0; i < Height; i++)
|
|
||||||
{
|
|
||||||
erri = i;
|
|
||||||
for (int j = SHP.Data[x].HeaderImage.x; j < Width; j++)
|
|
||||||
{
|
|
||||||
errj = j;
|
|
||||||
errl = l;
|
|
||||||
errk = k;
|
|
||||||
arroff = i + j + l;
|
|
||||||
|
|
||||||
if (((j + 1) > (SHP.Data[x].HeaderImage.cx + SHP.Data[x].HeaderImage.x)) || ((i + 1) > (SHP.Data[x].HeaderImage.cy)))
|
|
||||||
cp = 0;
|
|
||||||
else
|
|
||||||
cp = SHP.Data[x].Databuffer[i + (j - SHP.Data[x].HeaderImage.x) + l];
|
|
||||||
|
|
||||||
FData[i + j + k] = cp;
|
|
||||||
|
|
||||||
if (j == (SHP.Data[x].HeaderImage.cx + SHP.Data[x].HeaderImage.x - 1))
|
|
||||||
l = l + (SHP.Data[x].HeaderImage.cx - 1);
|
|
||||||
|
|
||||||
if (j == (Width - 1))
|
|
||||||
k = k + (Width - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//FData = headers[x - 1].Image;
|
|
||||||
k = 0;
|
|
||||||
for (int i = 0; i < (Height - SHP.Data[x].HeaderImage.y); i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < Width; j++)
|
|
||||||
{
|
|
||||||
headers[x - 1].Image[i + j + k + (Width * SHP.Data[x].HeaderImage.y)] = FData[i + j + k];
|
|
||||||
if (j == (Width - 1))
|
|
||||||
{
|
|
||||||
k = k + (Width - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Compression 2
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Compression 1
|
|
||||||
ImageSize = (int)(SHP.Data[x].HeaderImage.cx * SHP.Data[x].HeaderImage.cy);
|
|
||||||
Databuffer = new byte[ImageSize];
|
|
||||||
for (int i = 0; i < ImageSize; i++)
|
|
||||||
{
|
|
||||||
s.Seek(SHP.Data[x].HeaderImage.offset + i, SeekOrigin.Begin);
|
|
||||||
Databuffer[i] = s.ReadUInt8();
|
|
||||||
}
|
|
||||||
SHP.Data[x].Databuffer = new byte[(SHP.Data[x].HeaderImage.cx * SHP.Data[x].HeaderImage.cy)];
|
|
||||||
SHP.Data[x].Databuffer = Databuffer;
|
|
||||||
|
|
||||||
k = 0;
|
|
||||||
l = 0;
|
|
||||||
for (int i = 0; i < Height; i++)
|
|
||||||
{
|
|
||||||
erri = i;
|
|
||||||
for (int j = SHP.Data[x].HeaderImage.x; j < Width; j++)
|
|
||||||
{
|
|
||||||
errj = j;
|
|
||||||
errl = l;
|
|
||||||
errk = k;
|
|
||||||
arroff = i + j + l;
|
|
||||||
|
|
||||||
if (((j + 1) > (SHP.Data[x].HeaderImage.cx + SHP.Data[x].HeaderImage.x)) || ((i + 1) > (SHP.Data[x].HeaderImage.cy)))
|
|
||||||
cp = 0;
|
|
||||||
else
|
|
||||||
cp = SHP.Data[x].Databuffer[i + (j - SHP.Data[x].HeaderImage.x) + l];
|
|
||||||
|
|
||||||
FData[i + j + k] = cp;
|
|
||||||
|
|
||||||
if (j == (SHP.Data[x].HeaderImage.cx + SHP.Data[x].HeaderImage.x - 1))
|
|
||||||
l = l + (SHP.Data[x].HeaderImage.cx - 1);
|
|
||||||
|
|
||||||
if (j == (Width - 1))
|
|
||||||
k = k + (Width - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//FData = headers[x - 1].Image;
|
|
||||||
k = 0;
|
|
||||||
for (int i = 0; i < (Height - SHP.Data[x].HeaderImage.y); i++)
|
|
||||||
{
|
|
||||||
for (int j = 0; j < Width; j++)
|
|
||||||
{
|
|
||||||
headers[x - 1].Image[i + j + k + (Width * SHP.Data[x].HeaderImage.y)] = FData[i + j + k];
|
|
||||||
if (j == (Width - 1))
|
|
||||||
{
|
|
||||||
k = k + (Width - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine(e.Message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Set the shp's databuffer to the result after decompression
|
|
||||||
}
|
|
||||||
//Width = Width2;
|
|
||||||
//Height = Height2;
|
|
||||||
}
|
|
||||||
|
|
||||||
public HeaderImage this[int index]
|
|
||||||
{
|
|
||||||
get { return headers[index]; }
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ReInterpretWordFromBytes(byte Byte1, byte Byte2, ref ushort FullValue)
|
|
||||||
{
|
|
||||||
FullValue = (ushort)((Byte2 * 256) + Byte1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void ReInterpretWordFromBytes(byte Byte1, byte Byte2, ref uint FullValue)
|
|
||||||
{
|
|
||||||
FullValue = (uint)((Byte2 * 256) + Byte1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compression 3:
|
|
||||||
public static void Decode3(byte[] Source, ref byte[] Dest, int cx, int cy, ref int max)
|
|
||||||
{
|
|
||||||
int SP;
|
|
||||||
int DP;
|
|
||||||
int x;
|
|
||||||
int y;
|
|
||||||
int Count;
|
|
||||||
int v;
|
|
||||||
int maxdp;
|
|
||||||
ushort Pos;
|
|
||||||
maxdp = cx * cy;
|
|
||||||
SP = 0;
|
|
||||||
DP = 0;
|
|
||||||
Pos = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for (y = 1; y <= cy; y++)
|
|
||||||
{
|
|
||||||
ReInterpretWordFromBytes(Source[SP], Source[SP + 1], ref Pos);
|
|
||||||
|
|
||||||
Count = Pos - 2;
|
|
||||||
|
|
||||||
SP = SP + 2;
|
|
||||||
|
|
||||||
x = 0;
|
|
||||||
while (Count > 0)
|
|
||||||
{
|
|
||||||
Count = Count - 1;
|
|
||||||
if ((SP > max) || (DP > maxdp))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// SP has reached max value, exit
|
|
||||||
v = Source[SP];
|
|
||||||
SP++;
|
|
||||||
if (v != 0)
|
|
||||||
{
|
|
||||||
if ((SP > max) || (DP > maxdp))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
x++;
|
|
||||||
Dest[DP] += (byte)v;
|
|
||||||
}
|
|
||||||
DP++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Count -= 1;
|
|
||||||
v = Source[SP];
|
|
||||||
|
|
||||||
SP++;
|
|
||||||
if ((x + v) > cx)
|
|
||||||
{
|
|
||||||
v = cx - x;
|
|
||||||
}
|
|
||||||
x = x + v;
|
|
||||||
while (v > 0)
|
|
||||||
{
|
|
||||||
if ((SP > max) || (DP > maxdp))
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
v -= 1;
|
|
||||||
Dest[DP] = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
DP++;
|
|
||||||
// SP has reached max value, exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((SP >= max) || (DP >= maxdp))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// SP has reached max value, exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine(e.Message);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void Decode2(byte[] Source, ref byte[] Dest, int cx, int cy, ref int max)
|
|
||||||
{
|
|
||||||
int SP;
|
|
||||||
int DP;
|
|
||||||
int y;
|
|
||||||
int Count;
|
|
||||||
int maxdp;
|
|
||||||
ushort Pos;
|
|
||||||
maxdp = cx * cy;
|
|
||||||
SP = 0;
|
|
||||||
DP = 0;
|
|
||||||
Pos = 0;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
for (y = 1; y <= cy; y++)
|
|
||||||
{
|
|
||||||
ReInterpretWordFromBytes(Source[SP], Source[SP + 1], ref Pos);
|
|
||||||
Count = Pos - 2;
|
|
||||||
SP += 2;
|
|
||||||
while (Count > 0)
|
|
||||||
{
|
|
||||||
Count -= 1;
|
|
||||||
if ((SP > max) || (DP > maxdp))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// SP has reached max value, exit
|
|
||||||
Dest[DP] = Source[SP];
|
|
||||||
SP++;
|
|
||||||
DP++;
|
|
||||||
}
|
|
||||||
if ((SP >= max) || (DP >= maxdp))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// SP has reached max value, exit
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine(e.Message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerator<HeaderImage> GetEnumerator()
|
|
||||||
{
|
|
||||||
return headers.GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator()
|
|
||||||
{
|
|
||||||
return GetEnumerator();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Size Size { get { return new Size(Width, Height); } }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -44,7 +44,7 @@ namespace OpenRA.Graphics
|
|||||||
if (ImageCount == 0)
|
if (ImageCount == 0)
|
||||||
{
|
{
|
||||||
var shp = new ShpTSReader(FileSystem.OpenWithExts(filename, exts));
|
var shp = new ShpTSReader(FileSystem.OpenWithExts(filename, exts));
|
||||||
return shp.Select(a => SheetBuilder.Add(a.Image, shp.Size)).ToArray();
|
return shp.Frames.Select(a => SheetBuilder.Add(a.Image, a.Size, a.Offset)).ToArray();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user