Files
Dec2017-Script-Dump/Gif.Components/GifDecoder.cs
T
2026-06-04 11:42:34 +02:00

815 lines
17 KiB
C#

using System;
using System.Collections;
using System.IO;
using UnityEngine;
namespace Gif.Components
{
// Token: 0x02000006 RID: 6
public class GifDecoder
{
// Token: 0x06000023 RID: 35 RVA: 0x00002CFC File Offset: 0x000010FC
public int GetDelay(int n)
{
this.delay = -1;
if (n >= 0 && n < this.frameCount)
{
this.delay = ((GifDecoder.GifFrame)this.frames[n]).delay;
}
return this.delay;
}
// Token: 0x06000024 RID: 36 RVA: 0x00002D50 File Offset: 0x00001150
public int GetFrameCount()
{
return this.frameCount;
}
// Token: 0x06000025 RID: 37 RVA: 0x00002D6C File Offset: 0x0000116C
public Image GetImage()
{
return this.GetFrame(0);
}
// Token: 0x06000026 RID: 38 RVA: 0x00002D88 File Offset: 0x00001188
public int GetLoopCount()
{
return this.loopCount;
}
// Token: 0x06000027 RID: 39 RVA: 0x00002DA4 File Offset: 0x000011A4
private int[] GetPixels(Image bitmap)
{
int[] array = new int[3 * this.image.width * this.image.height];
int num = 0;
for (int i = 0; i < this.image.height; i++)
{
for (int j = 0; j < this.image.width; j++)
{
Color32 color = bitmap[j, i];
array[num] = (int)color.r;
num++;
array[num] = (int)color.g;
num++;
array[num] = (int)color.b;
num++;
}
}
return array;
}
// Token: 0x06000028 RID: 40 RVA: 0x00002E50 File Offset: 0x00001250
private void SetPixels(int[] pixels)
{
int num = 0;
for (int i = 0; i < this.image.height; i++)
{
for (int j = 0; j < this.image.width; j++)
{
int num2 = pixels[num++];
byte b = (byte)((num2 >> 16) & 255);
byte b2 = (byte)((num2 >> 8) & 255);
byte b3 = (byte)((num2 >> 0) & 255);
byte b4 = (byte)((num2 >> 24) & 255);
Color32 color = new Color32(b, b2, b3, b4);
this.bitmap[j, i] = color;
}
}
}
// Token: 0x06000029 RID: 41 RVA: 0x00002EF4 File Offset: 0x000012F4
protected void SetPixels()
{
int[] array = this.GetPixels(this.bitmap);
if (this.lastDispose > 0)
{
if (this.lastDispose == 3)
{
int num = this.frameCount - 2;
if (num > 0)
{
this.lastImage = this.GetFrame(num - 1);
}
else
{
this.lastImage = null;
}
}
if (this.lastImage != null)
{
int[] array2 = this.GetPixels(this.lastImage);
Array.Copy(array2, 0, array, 0, this.width * this.height);
if (this.lastDispose == 2)
{
Color32 color = default(Color32);
if (this.transparency)
{
color = new Color32(0, 0, 0, 0);
}
else
{
int num2 = this.lastBgColor;
byte b = (byte)((num2 >> 16) & 255);
byte b2 = (byte)((num2 >> 8) & 255);
byte b3 = (byte)((num2 >> 0) & 255);
byte b4 = (byte)((num2 >> 24) & 255);
color = new Color32(b, b2, b3, b4);
}
this.image.Fill(color, this.lastRect.xmin, this.lastRect.ymin, this.lastRect.xmax, this.lastRect.ymax);
}
}
}
int num3 = 1;
int num4 = 8;
int num5 = 0;
for (int i = 0; i < this.ih; i++)
{
int num6 = i;
if (this.interlace)
{
if (num5 >= this.ih)
{
num3++;
if (num3 != 2)
{
if (num3 != 3)
{
if (num3 == 4)
{
num5 = 1;
num4 = 2;
}
}
else
{
num5 = 2;
num4 = 4;
}
}
else
{
num5 = 4;
}
}
num6 = num5;
num5 += num4;
}
num6 += this.iy;
if (num6 < this.height)
{
int num7 = num6 * this.width;
int j = num7 + this.ix;
int num8 = j + this.iw;
if (num7 + this.width < num8)
{
num8 = num7 + this.width;
}
int num9 = i * this.iw;
while (j < num8)
{
int num10 = (int)(this.pixels[num9++] & byte.MaxValue);
int num11 = this.act[num10];
if (num11 != 0)
{
array[j] = num11;
}
j++;
}
}
}
this.SetPixels(array);
}
// Token: 0x0600002A RID: 42 RVA: 0x00003188 File Offset: 0x00001588
public Image GetFrame(int n)
{
Image image = null;
if (n >= 0 && n < this.frameCount)
{
image = ((GifDecoder.GifFrame)this.frames[n]).image;
}
return image;
}
// Token: 0x0600002B RID: 43 RVA: 0x000031CC File Offset: 0x000015CC
public Size GetFrameSize()
{
return new Size(this.width, this.height);
}
// Token: 0x0600002C RID: 44 RVA: 0x000031F4 File Offset: 0x000015F4
public int Read(Stream inStream)
{
this.Init();
if (inStream != null)
{
this.inStream = inStream;
this.ReadHeader();
if (!this.Error())
{
this.ReadContents();
if (this.frameCount < 0)
{
this.status = GifDecoder.STATUS_FORMAT_ERROR;
}
}
inStream.Close();
}
else
{
this.status = GifDecoder.STATUS_OPEN_ERROR;
}
return this.status;
}
// Token: 0x0600002D RID: 45 RVA: 0x00003270 File Offset: 0x00001670
public int Read(string name)
{
this.status = GifDecoder.STATUS_OK;
try
{
name = name.Trim().ToLower();
this.status = this.Read(new FileInfo(name).OpenRead());
}
catch (IOException ex)
{
this.status = GifDecoder.STATUS_OPEN_ERROR;
}
return this.status;
}
// Token: 0x0600002E RID: 46 RVA: 0x000032E4 File Offset: 0x000016E4
protected void DecodeImageData()
{
int num = -1;
int num2 = this.iw * this.ih;
if (this.pixels == null || this.pixels.Length < num2)
{
this.pixels = new byte[num2];
}
if (this.prefix == null)
{
this.prefix = new short[GifDecoder.MaxStackSize];
}
if (this.suffix == null)
{
this.suffix = new byte[GifDecoder.MaxStackSize];
}
if (this.pixelStack == null)
{
this.pixelStack = new byte[GifDecoder.MaxStackSize + 1];
}
int num3 = this.Read();
int num4 = 1 << num3;
int num5 = num4 + 1;
int num6 = num4 + 2;
int num7 = num;
int num8 = num3 + 1;
int num9 = (1 << num8) - 1;
for (int i = 0; i < num4; i++)
{
this.prefix[i] = 0;
this.suffix[i] = (byte)i;
}
int num16;
int num15;
int num14;
int num13;
int num12;
int num11;
int num10 = (num11 = (num12 = (num13 = (num14 = (num15 = (num16 = 0))))));
for (int j = 0; j < num2; j++)
{
if (num14 == 0)
{
if (num10 < num8)
{
if (num12 == 0)
{
num12 = this.ReadBlock();
if (num12 <= 0)
{
break;
}
num16 = 0;
}
num11 += (int)(this.block[num16] & byte.MaxValue) << num10;
num10 += 8;
num16++;
num12--;
continue;
}
int i = num11 & num9;
num11 >>= num8;
num10 -= num8;
if (i > num6 || i == num5)
{
break;
}
if (i == num4)
{
num8 = num3 + 1;
num9 = (1 << num8) - 1;
num6 = num4 + 2;
num7 = num;
continue;
}
if (num7 == num)
{
this.pixelStack[num14++] = this.suffix[i];
num7 = i;
num13 = i;
continue;
}
int num17 = i;
if (i == num6)
{
this.pixelStack[num14++] = (byte)num13;
i = num7;
}
while (i > num4)
{
this.pixelStack[num14++] = this.suffix[i];
i = (int)this.prefix[i];
}
num13 = (int)(this.suffix[i] & byte.MaxValue);
if (num6 >= GifDecoder.MaxStackSize)
{
break;
}
this.pixelStack[num14++] = (byte)num13;
this.prefix[num6] = (short)num7;
this.suffix[num6] = (byte)num13;
num6++;
if ((num6 & num9) == 0 && num6 < GifDecoder.MaxStackSize)
{
num8++;
num9 += num6;
}
num7 = num17;
}
num14--;
this.pixels[num15++] = this.pixelStack[num14];
}
for (int j = num15; j < num2; j++)
{
this.pixels[j] = 0;
}
}
// Token: 0x0600002F RID: 47 RVA: 0x000035F0 File Offset: 0x000019F0
protected bool Error()
{
return this.status != GifDecoder.STATUS_OK;
}
// Token: 0x06000030 RID: 48 RVA: 0x00003615 File Offset: 0x00001A15
protected void Init()
{
this.status = GifDecoder.STATUS_OK;
this.frameCount = 0;
this.frames = new ArrayList();
this.gct = null;
this.lct = null;
}
// Token: 0x06000031 RID: 49 RVA: 0x00003644 File Offset: 0x00001A44
protected int Read()
{
int num = 0;
try
{
num = this.inStream.ReadByte();
}
catch (IOException ex)
{
this.status = GifDecoder.STATUS_FORMAT_ERROR;
}
return num;
}
// Token: 0x06000032 RID: 50 RVA: 0x00003694 File Offset: 0x00001A94
protected int ReadBlock()
{
this.blockSize = this.Read();
int i = 0;
if (this.blockSize > 0)
{
try
{
while (i < this.blockSize)
{
int num = this.inStream.Read(this.block, i, this.blockSize - i);
if (num == -1)
{
break;
}
i += num;
}
}
catch (IOException ex)
{
}
if (i < this.blockSize)
{
this.status = GifDecoder.STATUS_FORMAT_ERROR;
}
}
return i;
}
// Token: 0x06000033 RID: 51 RVA: 0x00003740 File Offset: 0x00001B40
protected int[] ReadColorTable(int ncolors)
{
int num = 3 * ncolors;
int[] array = null;
byte[] array2 = new byte[num];
int num2 = 0;
try
{
num2 = this.inStream.Read(array2, 0, array2.Length);
}
catch (IOException ex)
{
}
if (num2 < num)
{
this.status = GifDecoder.STATUS_FORMAT_ERROR;
}
else
{
array = new int[256];
int i = 0;
int num3 = 0;
while (i < ncolors)
{
int num4 = (int)(array2[num3++] & byte.MaxValue);
int num5 = (int)(array2[num3++] & byte.MaxValue);
int num6 = (int)(array2[num3++] & byte.MaxValue);
array[i++] = (int)((ulong)(-16777216) | (ulong)((long)((long)num4 << 16)) | (ulong)((long)((long)num5 << 8)) | (ulong)((long)num6));
}
}
return array;
}
// Token: 0x06000034 RID: 52 RVA: 0x00003828 File Offset: 0x00001C28
protected void ReadContents()
{
bool flag = false;
while (!flag && !this.Error())
{
int num = this.Read();
if (num != 0)
{
if (num != 33)
{
if (num != 44)
{
if (num != 59)
{
this.status = GifDecoder.STATUS_FORMAT_ERROR;
}
else
{
flag = true;
}
}
else
{
this.ReadImage();
}
}
else
{
num = this.Read();
if (num != 249)
{
if (num != 255)
{
this.Skip();
}
else
{
this.ReadBlock();
string text = "";
for (int i = 0; i < 11; i++)
{
text += (char)this.block[i];
}
if (text.Equals("NETSCAPE2.0"))
{
this.ReadNetscapeExt();
}
else
{
this.Skip();
}
}
}
else
{
this.ReadGraphicControlExt();
}
}
}
}
}
// Token: 0x06000035 RID: 53 RVA: 0x00003940 File Offset: 0x00001D40
protected void ReadGraphicControlExt()
{
this.Read();
int num = this.Read();
this.dispose = (num & 28) >> 2;
if (this.dispose == 0)
{
this.dispose = 1;
}
this.transparency = (num & 1) != 0;
this.delay = this.ReadShort() * 10;
this.transIndex = this.Read();
this.Read();
}
// Token: 0x06000036 RID: 54 RVA: 0x000039B0 File Offset: 0x00001DB0
protected void ReadHeader()
{
string text = "";
for (int i = 0; i < 6; i++)
{
text += (char)this.Read();
}
if (!text.StartsWith("GIF"))
{
this.status = GifDecoder.STATUS_FORMAT_ERROR;
}
else
{
this.ReadLSD();
if (this.gctFlag && !this.Error())
{
this.gct = this.ReadColorTable(this.gctSize);
this.bgColor = this.gct[this.bgIndex];
}
}
}
// Token: 0x06000037 RID: 55 RVA: 0x00003A50 File Offset: 0x00001E50
protected void ReadImage()
{
this.ix = this.ReadShort();
this.iy = this.ReadShort();
this.iw = this.ReadShort();
this.ih = this.ReadShort();
int num = this.Read();
this.lctFlag = (num & 128) != 0;
this.interlace = (num & 64) != 0;
this.lctSize = 2 << (num & 7);
if (this.lctFlag)
{
this.lct = this.ReadColorTable(this.lctSize);
this.act = this.lct;
}
else
{
this.act = this.gct;
if (this.bgIndex == this.transIndex)
{
this.bgColor = 0;
}
}
int num2 = 0;
if (this.transparency)
{
num2 = this.act[this.transIndex];
this.act[this.transIndex] = 0;
}
if (this.act == null)
{
this.status = GifDecoder.STATUS_FORMAT_ERROR;
}
if (!this.Error())
{
this.DecodeImageData();
this.Skip();
if (!this.Error())
{
this.frameCount++;
this.bitmap = new Image(this.width, this.height);
this.image = this.bitmap;
this.SetPixels();
this.frames.Add(new GifDecoder.GifFrame(this.bitmap, this.delay));
if (this.transparency)
{
this.act[this.transIndex] = num2;
}
this.ResetFrame();
}
}
}
// Token: 0x06000038 RID: 56 RVA: 0x00003C00 File Offset: 0x00002000
protected void ReadLSD()
{
this.width = this.ReadShort();
this.height = this.ReadShort();
int num = this.Read();
this.gctFlag = (num & 128) != 0;
this.gctSize = 2 << (num & 7);
this.bgIndex = this.Read();
this.pixelAspect = this.Read();
}
// Token: 0x06000039 RID: 57 RVA: 0x00003C68 File Offset: 0x00002068
protected void ReadNetscapeExt()
{
do
{
this.ReadBlock();
if (this.block[0] == 1)
{
int num = (int)(this.block[1] & byte.MaxValue);
int num2 = (int)(this.block[2] & byte.MaxValue);
this.loopCount = (num2 << 8) | num;
}
}
while (this.blockSize > 0 && !this.Error());
}
// Token: 0x0600003A RID: 58 RVA: 0x00003CD0 File Offset: 0x000020D0
protected int ReadShort()
{
return this.Read() | (this.Read() << 8);
}
// Token: 0x0600003B RID: 59 RVA: 0x00003CF4 File Offset: 0x000020F4
protected void ResetFrame()
{
this.lastDispose = this.dispose;
this.lastRect = new Rectangle
{
xmin = this.ix,
ymin = this.iy,
xmax = this.ix + this.iw,
ymax = this.iy + this.ih
};
this.lastImage = this.image;
this.lastBgColor = this.bgColor;
this.lct = null;
}
// Token: 0x0600003C RID: 60 RVA: 0x00003D82 File Offset: 0x00002182
protected void Skip()
{
do
{
this.ReadBlock();
}
while (this.blockSize > 0 && !this.Error());
}
// Token: 0x04000025 RID: 37
public static readonly int STATUS_OK = 0;
// Token: 0x04000026 RID: 38
public static readonly int STATUS_FORMAT_ERROR = 1;
// Token: 0x04000027 RID: 39
public static readonly int STATUS_OPEN_ERROR = 2;
// Token: 0x04000028 RID: 40
protected Stream inStream;
// Token: 0x04000029 RID: 41
protected int status;
// Token: 0x0400002A RID: 42
protected int width;
// Token: 0x0400002B RID: 43
protected int height;
// Token: 0x0400002C RID: 44
protected bool gctFlag;
// Token: 0x0400002D RID: 45
protected int gctSize;
// Token: 0x0400002E RID: 46
protected int loopCount = 1;
// Token: 0x0400002F RID: 47
protected int[] gct;
// Token: 0x04000030 RID: 48
protected int[] lct;
// Token: 0x04000031 RID: 49
protected int[] act;
// Token: 0x04000032 RID: 50
protected int bgIndex;
// Token: 0x04000033 RID: 51
protected int bgColor;
// Token: 0x04000034 RID: 52
protected int lastBgColor;
// Token: 0x04000035 RID: 53
protected int pixelAspect;
// Token: 0x04000036 RID: 54
protected bool lctFlag;
// Token: 0x04000037 RID: 55
protected bool interlace;
// Token: 0x04000038 RID: 56
protected int lctSize;
// Token: 0x04000039 RID: 57
protected int ix;
// Token: 0x0400003A RID: 58
protected int iy;
// Token: 0x0400003B RID: 59
protected int iw;
// Token: 0x0400003C RID: 60
protected int ih;
// Token: 0x0400003D RID: 61
protected Rectangle lastRect;
// Token: 0x0400003E RID: 62
protected Image image;
// Token: 0x0400003F RID: 63
protected Image bitmap;
// Token: 0x04000040 RID: 64
protected Image lastImage;
// Token: 0x04000041 RID: 65
protected byte[] block = new byte[256];
// Token: 0x04000042 RID: 66
protected int blockSize = 0;
// Token: 0x04000043 RID: 67
protected int dispose = 0;
// Token: 0x04000044 RID: 68
protected int lastDispose = 0;
// Token: 0x04000045 RID: 69
protected bool transparency = false;
// Token: 0x04000046 RID: 70
protected int delay = 0;
// Token: 0x04000047 RID: 71
protected int transIndex;
// Token: 0x04000048 RID: 72
protected static readonly int MaxStackSize = 4096;
// Token: 0x04000049 RID: 73
protected short[] prefix;
// Token: 0x0400004A RID: 74
protected byte[] suffix;
// Token: 0x0400004B RID: 75
protected byte[] pixelStack;
// Token: 0x0400004C RID: 76
protected byte[] pixels;
// Token: 0x0400004D RID: 77
protected ArrayList frames;
// Token: 0x0400004E RID: 78
protected int frameCount;
// Token: 0x02000007 RID: 7
public class GifFrame
{
// Token: 0x0600003E RID: 62 RVA: 0x00003DC3 File Offset: 0x000021C3
public GifFrame(Image im, int del)
{
this.image = im;
this.delay = del;
}
// Token: 0x0400004F RID: 79
public Image image;
// Token: 0x04000050 RID: 80
public int delay;
}
}
}