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]; } }