117 lines
4.9 KiB
C#
117 lines
4.9 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: SEGATools.Graphics.MRImageConverter
|
|
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
|
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
|
// Assembly location: SEGATools.dll
|
|
|
|
using System;
|
|
using System.Drawing;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
|
|
namespace SEGATools.Graphics
|
|
{
|
|
public class MRImageConverter
|
|
{
|
|
private static readonly string MR_ID = "MR";
|
|
private static readonly int MR_HEADER_OFFSET = 2;
|
|
private static readonly int MR_COLOR_PALETTE_OFFSET = MRImageConverter.MR_HEADER_OFFSET + 28;
|
|
private static readonly int MR_HEADER_MINIMUM_SIZE = 30;
|
|
private static readonly int MR_COLOR_SIZE = 4;
|
|
|
|
public static MRImage ToMRImage(byte[] buffer, int startIndex)
|
|
{
|
|
if (startIndex < 0 || buffer.Length - startIndex < MRImageConverter.MR_HEADER_MINIMUM_SIZE)
|
|
throw new ArgumentOutOfRangeException();
|
|
string str = Encoding.ASCII.GetString(buffer, startIndex, MRImageConverter.MR_ID.Length);
|
|
if (!MRImageConverter.MR_ID.Equals(str))
|
|
throw new MRImageIdentifierMissingException("Wrong MR file identifier");
|
|
MRImageHeader structure1 = (MRImageHeader) Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement((Array) buffer, startIndex + MRImageConverter.MR_HEADER_OFFSET), typeof (MRImageHeader));
|
|
if (structure1.NumberOfColors <= 0U || (long) (buffer.Length - startIndex - MRImageConverter.MR_COLOR_PALETTE_OFFSET) < (long) structure1.NumberOfColors * (long) MRImageConverter.MR_COLOR_SIZE)
|
|
throw new MRImageDecompressionException("Color palette too big");
|
|
Color[] colorArray = new Color[(int) structure1.NumberOfColors];
|
|
for (int index1 = 0; index1 < colorArray.Length; ++index1)
|
|
{
|
|
int index2 = startIndex + MRImageConverter.MR_COLOR_PALETTE_OFFSET + index1 * MRImageConverter.MR_COLOR_SIZE;
|
|
MRImageColor structure2 = (MRImageColor) Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement((Array) buffer, index2), typeof (MRImageColor));
|
|
colorArray[index1] = Color.FromArgb((int) structure2.Alpha, (int) structure2.Red, (int) structure2.Green, (int) structure2.Blue);
|
|
}
|
|
int length = structure1.Size - structure1.Offset;
|
|
int startIndex1 = startIndex + structure1.Offset;
|
|
try
|
|
{
|
|
byte[] rawData = new byte[structure1.Size];
|
|
Buffer.BlockCopy((Array) buffer, startIndex, (Array) rawData, 0, rawData.Length);
|
|
byte[] pixels = MRImageConverter.DecompressPixelData(structure1, colorArray, buffer, startIndex1, length);
|
|
return new MRImage(structure1, colorArray, pixels, startIndex, rawData);
|
|
}
|
|
catch (MRImageUnknownColorException ex)
|
|
{
|
|
throw new MRImageDecompressionException("Unable to decompress the image", (Exception) ex);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new MRImageDecompressionException("Unable to decompress the image", ex);
|
|
}
|
|
}
|
|
|
|
private static byte[] DecompressPixelData(
|
|
MRImageHeader mrHeader,
|
|
Color[] palette,
|
|
byte[] buffer,
|
|
int startIndex,
|
|
int length)
|
|
{
|
|
int length1 = palette.Length;
|
|
int index1 = 0;
|
|
byte[] buffer1 = new byte[mrHeader.Width * mrHeader.Height];
|
|
for (int index2 = startIndex; index2 < startIndex + length; ++index2)
|
|
{
|
|
if (buffer[index2] < (byte) 128)
|
|
{
|
|
byte colorNumber = buffer[index2];
|
|
index1 = MRImageConverter.decodePixels(buffer1, index1, colorNumber, length1, 1);
|
|
}
|
|
else if (buffer[index2] == (byte) 129)
|
|
{
|
|
int numberOfPixels = (int) buffer[index2 + 1];
|
|
byte colorNumber = buffer[index2 + 2];
|
|
index1 = MRImageConverter.decodePixels(buffer1, index1, colorNumber, length1, numberOfPixels);
|
|
index2 += 2;
|
|
}
|
|
else if (buffer[index2] == (byte) 130 && buffer[index2 + 1] >= (byte) 128)
|
|
{
|
|
int numberOfPixels = (int) buffer[index2 + 1] - 128 + 256;
|
|
byte colorNumber = buffer[index2 + 2];
|
|
index1 = MRImageConverter.decodePixels(buffer1, index1, colorNumber, length1, numberOfPixels);
|
|
index2 += 2;
|
|
}
|
|
else
|
|
{
|
|
int numberOfPixels = (int) buffer[index2] - 128;
|
|
byte colorNumber = buffer[index2 + 1];
|
|
index1 = MRImageConverter.decodePixels(buffer1, index1, colorNumber, length1, numberOfPixels);
|
|
++index2;
|
|
}
|
|
}
|
|
return buffer1;
|
|
}
|
|
|
|
private static int decodePixels(
|
|
byte[] buffer,
|
|
int index,
|
|
byte colorNumber,
|
|
int numberOfColors,
|
|
int numberOfPixels)
|
|
{
|
|
for (int index1 = 0; index1 < numberOfPixels && index < buffer.Length; ++index1)
|
|
{
|
|
if ((int) colorNumber >= numberOfColors)
|
|
colorNumber = colorNumber == (byte) 154 ? (byte) 0 : throw MRImageUnknownColorException.anUnknownColor(colorNumber);
|
|
buffer[index] = colorNumber;
|
|
++index;
|
|
}
|
|
return index;
|
|
}
|
|
}
|
|
}
|