Files
2026-06-04 11:42:34 +02:00

311 lines
6.6 KiB
C#

using System;
using System.IO;
namespace Gif.Components
{
// Token: 0x02000008 RID: 8
public class LZWEncoder
{
// Token: 0x0600003F RID: 63 RVA: 0x00003DDC File Offset: 0x000021DC
public LZWEncoder(int width, int height, byte[] pixels, int color_depth)
{
this.imgW = width;
this.imgH = height;
this.pixAry = pixels;
this.initCodeSize = Math.Max(2, color_depth);
}
// Token: 0x06000040 RID: 64 RVA: 0x00003EA0 File Offset: 0x000022A0
private void Add(byte c, Stream outs)
{
this.accum[this.a_count++] = c;
if (this.a_count >= 254)
{
this.Flush(outs);
}
}
// Token: 0x06000041 RID: 65 RVA: 0x00003EDE File Offset: 0x000022DE
private void ClearTable(Stream outs)
{
this.ResetCodeTable(this.hsize);
this.free_ent = this.ClearCode + 2;
this.clear_flg = true;
this.Output(this.ClearCode, outs);
}
// Token: 0x06000042 RID: 66 RVA: 0x00003F10 File Offset: 0x00002310
private void ResetCodeTable(int hsize)
{
for (int i = 0; i < hsize; i++)
{
this.htab[i] = -1;
}
}
// Token: 0x06000043 RID: 67 RVA: 0x00003F3C File Offset: 0x0000233C
private void Compress(int init_bits, Stream outs)
{
this.g_init_bits = init_bits;
this.clear_flg = false;
this.n_bits = this.g_init_bits;
this.maxcode = this.MaxCode(this.n_bits);
this.ClearCode = 1 << init_bits - 1;
this.EOFCode = this.ClearCode + 1;
this.free_ent = this.ClearCode + 2;
this.a_count = 0;
int num = this.NextPixel();
int num2 = 0;
for (int i = this.hsize; i < 65536; i *= 2)
{
num2++;
}
num2 = 8 - num2;
int num3 = this.hsize;
this.ResetCodeTable(num3);
this.Output(this.ClearCode, outs);
for (;;)
{
int num4;
while ((num4 = this.NextPixel()) != LZWEncoder.EOF)
{
int i = (num4 << this.maxbits) + num;
int num5 = (num4 << num2) ^ num;
if (this.htab[num5] == i)
{
num = this.codetab[num5];
}
else
{
if (this.htab[num5] >= 0)
{
int num6 = num3 - num5;
if (num5 == 0)
{
num6 = 1;
}
for (;;)
{
if ((num5 -= num6) < 0)
{
num5 += num3;
}
if (this.htab[num5] == i)
{
break;
}
if (this.htab[num5] < 0)
{
goto IL_144;
}
}
num = this.codetab[num5];
continue;
}
IL_144:
this.Output(num, outs);
num = num4;
if (this.free_ent < this.maxmaxcode)
{
this.codetab[num5] = this.free_ent++;
this.htab[num5] = i;
}
else
{
this.ClearTable(outs);
}
}
}
break;
}
this.Output(num, outs);
this.Output(this.EOFCode, outs);
}
// Token: 0x06000044 RID: 68 RVA: 0x00004104 File Offset: 0x00002504
public void Encode(Stream os)
{
os.WriteByte(Convert.ToByte(this.initCodeSize));
this.remaining = this.imgW * this.imgH;
this.curPixel = 0;
this.Compress(this.initCodeSize + 1, os);
os.WriteByte(0);
}
// Token: 0x06000045 RID: 69 RVA: 0x00004153 File Offset: 0x00002553
private void Flush(Stream outs)
{
if (this.a_count > 0)
{
outs.WriteByte(Convert.ToByte(this.a_count));
outs.Write(this.accum, 0, this.a_count);
this.a_count = 0;
}
}
// Token: 0x06000046 RID: 70 RVA: 0x00004190 File Offset: 0x00002590
private int MaxCode(int n_bits)
{
return (1 << n_bits) - 1;
}
// Token: 0x06000047 RID: 71 RVA: 0x000041B0 File Offset: 0x000025B0
private int NextPixel()
{
int num;
if (this.remaining == 0)
{
num = LZWEncoder.EOF;
}
else
{
this.remaining--;
int num2 = this.curPixel + 1;
if (num2 < this.pixAry.GetUpperBound(0))
{
byte b = this.pixAry[this.curPixel++];
num = (int)(b & byte.MaxValue);
}
else
{
num = 255;
}
}
return num;
}
// Token: 0x06000048 RID: 72 RVA: 0x00004230 File Offset: 0x00002630
private void Output(int code, Stream outs)
{
this.cur_accum &= this.masks[this.cur_bits];
if (this.cur_bits > 0)
{
this.cur_accum |= code << this.cur_bits;
}
else
{
this.cur_accum = code;
}
this.cur_bits += this.n_bits;
while (this.cur_bits >= 8)
{
this.Add((byte)(this.cur_accum & 255), outs);
this.cur_accum >>= 8;
this.cur_bits -= 8;
}
if (this.free_ent > this.maxcode || this.clear_flg)
{
if (this.clear_flg)
{
this.maxcode = this.MaxCode(this.n_bits = this.g_init_bits);
this.clear_flg = false;
}
else
{
this.n_bits++;
if (this.n_bits == this.maxbits)
{
this.maxcode = this.maxmaxcode;
}
else
{
this.maxcode = this.MaxCode(this.n_bits);
}
}
}
if (code == this.EOFCode)
{
while (this.cur_bits > 0)
{
this.Add((byte)(this.cur_accum & 255), outs);
this.cur_accum >>= 8;
this.cur_bits -= 8;
}
this.Flush(outs);
}
}
// Token: 0x04000051 RID: 81
private static readonly int EOF = -1;
// Token: 0x04000052 RID: 82
private int imgW;
// Token: 0x04000053 RID: 83
private int imgH;
// Token: 0x04000054 RID: 84
private byte[] pixAry;
// Token: 0x04000055 RID: 85
private int initCodeSize;
// Token: 0x04000056 RID: 86
private int remaining;
// Token: 0x04000057 RID: 87
private int curPixel;
// Token: 0x04000058 RID: 88
private static readonly int BITS = 12;
// Token: 0x04000059 RID: 89
private static readonly int HSIZE = 5003;
// Token: 0x0400005A RID: 90
private int n_bits;
// Token: 0x0400005B RID: 91
private int maxbits = LZWEncoder.BITS;
// Token: 0x0400005C RID: 92
private int maxcode;
// Token: 0x0400005D RID: 93
private int maxmaxcode = 1 << LZWEncoder.BITS;
// Token: 0x0400005E RID: 94
private int[] htab = new int[LZWEncoder.HSIZE];
// Token: 0x0400005F RID: 95
private int[] codetab = new int[LZWEncoder.HSIZE];
// Token: 0x04000060 RID: 96
private int hsize = LZWEncoder.HSIZE;
// Token: 0x04000061 RID: 97
private int free_ent = 0;
// Token: 0x04000062 RID: 98
private bool clear_flg = false;
// Token: 0x04000063 RID: 99
private int g_init_bits;
// Token: 0x04000064 RID: 100
private int ClearCode;
// Token: 0x04000065 RID: 101
private int EOFCode;
// Token: 0x04000066 RID: 102
private int cur_accum = 0;
// Token: 0x04000067 RID: 103
private int cur_bits = 0;
// Token: 0x04000068 RID: 104
private int[] masks = new int[]
{
0, 1, 3, 7, 15, 31, 63, 127, 255, 511,
1023, 2047, 4095, 8191, 16383, 32767, 65535
};
// Token: 0x04000069 RID: 105
private int a_count;
// Token: 0x0400006A RID: 106
private byte[] accum = new byte[256];
}
}