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

512 lines
12 KiB
C#

using System;
namespace Gif.Components
{
// Token: 0x02000009 RID: 9
public class NeuQuant
{
// Token: 0x0600004A RID: 74 RVA: 0x000043E8 File Offset: 0x000027E8
public NeuQuant(byte[] thepic, int len, int sample, int paletteSize = 256)
{
this.netsize = paletteSize;
this.initrad = this.netsize >> 3;
this.maxnetpos = this.netsize - 1;
this.initradius = this.initrad * NeuQuant.radiusbias;
this.bias = new int[this.netsize];
this.freq = new int[this.netsize];
this.radpower = new int[this.initrad];
this.thepicture = thepic;
this.lengthcount = len;
this.samplefac = sample;
this.network = new int[this.netsize][];
for (int i = 0; i < this.netsize; i++)
{
this.network[i] = new int[4];
int[] array = this.network[i];
array[0] = (array[1] = (array[2] = (i << NeuQuant.netbiasshift + 8) / this.netsize));
this.freq[i] = NeuQuant.intbias / this.netsize;
this.bias[i] = 0;
}
}
// Token: 0x0600004B RID: 75 RVA: 0x0000450C File Offset: 0x0000290C
public byte[] ColorMap()
{
byte[] array = new byte[3 * this.netsize];
int[] array2 = new int[this.netsize];
for (int i = 0; i < this.netsize; i++)
{
array2[this.network[i][3]] = i;
}
int num = 0;
for (int j = 0; j < this.netsize; j++)
{
int num2 = array2[j];
array[num++] = (byte)this.network[num2][0];
array[num++] = (byte)this.network[num2][1];
array[num++] = (byte)this.network[num2][2];
}
return array;
}
// Token: 0x0600004C RID: 76 RVA: 0x000045C0 File Offset: 0x000029C0
public void Inxbuild()
{
int num = 0;
int num2 = 0;
for (int i = 0; i < this.netsize; i++)
{
int[] array = this.network[i];
int num3 = i;
int num4 = array[1];
int[] array2;
for (int j = i + 1; j < this.netsize; j++)
{
array2 = this.network[j];
if (array2[1] < num4)
{
num3 = j;
num4 = array2[1];
}
}
array2 = this.network[num3];
if (i != num3)
{
int j = array2[0];
array2[0] = array[0];
array[0] = j;
j = array2[1];
array2[1] = array[1];
array[1] = j;
j = array2[2];
array2[2] = array[2];
array[2] = j;
j = array2[3];
array2[3] = array[3];
array[3] = j;
}
if (num4 != num)
{
this.netindex[num] = num2 + i >> 1;
for (int j = num + 1; j < num4; j++)
{
this.netindex[j] = i;
}
num = num4;
num2 = i;
}
}
this.netindex[num] = num2 + this.maxnetpos >> 1;
for (int j = num + 1; j < 256; j++)
{
this.netindex[j] = this.maxnetpos;
}
}
// Token: 0x0600004D RID: 77 RVA: 0x0000470C File Offset: 0x00002B0C
public void Learn()
{
if (this.lengthcount < NeuQuant.minpicturebytes)
{
this.samplefac = 1;
}
this.alphadec = 30 + (this.samplefac - 1) / 3;
byte[] array = this.thepicture;
int num = 0;
int num2 = this.lengthcount;
int num3 = this.lengthcount / (3 * this.samplefac);
int num4 = num3 / NeuQuant.ncycles;
int num5 = NeuQuant.initalpha;
int num6 = this.initradius;
int num7 = num6 >> NeuQuant.radiusbiasshift;
if (num7 <= 1)
{
num7 = 0;
}
int i;
for (i = 0; i < num7; i++)
{
this.radpower[i] = num5 * ((num7 * num7 - i * i) * NeuQuant.radbias / (num7 * num7));
}
int num8;
if (this.lengthcount < NeuQuant.minpicturebytes)
{
num8 = 3;
}
else if (this.lengthcount % NeuQuant.prime1 != 0)
{
num8 = 3 * NeuQuant.prime1;
}
else if (this.lengthcount % NeuQuant.prime2 != 0)
{
num8 = 3 * NeuQuant.prime2;
}
else if (this.lengthcount % NeuQuant.prime3 != 0)
{
num8 = 3 * NeuQuant.prime3;
}
else
{
num8 = 3 * NeuQuant.prime4;
}
i = 0;
while (i < num3)
{
int num9 = (int)(array[num] & byte.MaxValue) << NeuQuant.netbiasshift;
int num10 = (int)(array[num + 1] & byte.MaxValue) << NeuQuant.netbiasshift;
int num11 = (int)(array[num + 2] & byte.MaxValue) << NeuQuant.netbiasshift;
int j = this.Contest(num9, num10, num11);
this.Altersingle(num5, j, num9, num10, num11);
if (num7 != 0)
{
this.Alterneigh(num7, j, num9, num10, num11);
}
num += num8;
if (num >= num2)
{
num -= this.lengthcount;
}
i++;
if (num4 == 0)
{
num4 = 1;
}
if (i % num4 == 0)
{
num5 -= num5 / this.alphadec;
num6 -= num6 / NeuQuant.radiusdec;
num7 = num6 >> NeuQuant.radiusbiasshift;
if (num7 <= 1)
{
num7 = 0;
}
for (j = 0; j < num7; j++)
{
this.radpower[j] = num5 * ((num7 * num7 - j * j) * NeuQuant.radbias / (num7 * num7));
}
}
}
}
// Token: 0x0600004E RID: 78 RVA: 0x0000496C File Offset: 0x00002D6C
public int Map(int b, int g, int r)
{
int num = 1000;
int num2 = -1;
int num3 = this.netindex[g];
int num4 = num3 - 1;
while (num3 < this.netsize || num4 >= 0)
{
if (num3 < this.netsize)
{
int[] array = this.network[num3];
int num5 = array[1] - g;
if (num5 >= num)
{
num3 = this.netsize;
}
else
{
num3++;
if (num5 < 0)
{
num5 = -num5;
}
int num6 = array[0] - b;
if (num6 < 0)
{
num6 = -num6;
}
num5 += num6;
if (num5 < num)
{
num6 = array[2] - r;
if (num6 < 0)
{
num6 = -num6;
}
num5 += num6;
if (num5 < num)
{
num = num5;
num2 = array[3];
}
}
}
}
if (num4 >= 0)
{
int[] array = this.network[num4];
int num5 = g - array[1];
if (num5 >= num)
{
num4 = -1;
}
else
{
num4--;
if (num5 < 0)
{
num5 = -num5;
}
int num6 = array[0] - b;
if (num6 < 0)
{
num6 = -num6;
}
num5 += num6;
if (num5 < num)
{
num6 = array[2] - r;
if (num6 < 0)
{
num6 = -num6;
}
num5 += num6;
if (num5 < num)
{
num = num5;
num2 = array[3];
}
}
}
}
}
return num2;
}
// Token: 0x0600004F RID: 79 RVA: 0x00004AC0 File Offset: 0x00002EC0
public byte[] Process()
{
this.Learn();
this.Unbiasnet();
this.Inxbuild();
return this.ColorMap();
}
// Token: 0x06000050 RID: 80 RVA: 0x00004AF0 File Offset: 0x00002EF0
public void Unbiasnet()
{
for (int i = 0; i < this.netsize; i++)
{
this.network[i][0] >>= NeuQuant.netbiasshift;
this.network[i][1] >>= NeuQuant.netbiasshift;
this.network[i][2] >>= NeuQuant.netbiasshift;
this.network[i][3] = i;
}
}
// Token: 0x06000051 RID: 81 RVA: 0x00004B70 File Offset: 0x00002F70
protected void Alterneigh(int rad, int i, int b, int g, int r)
{
int num = i - rad;
if (num < -1)
{
num = -1;
}
int num2 = i + rad;
if (num2 > this.netsize)
{
num2 = this.netsize;
}
int num3 = i + 1;
int num4 = i - 1;
int num5 = 1;
while (num3 < num2 || num4 > num)
{
int num6 = this.radpower[num5++];
if (num3 < num2)
{
int[] array = this.network[num3++];
try
{
array[0] -= num6 * (array[0] - b) / NeuQuant.alpharadbias;
array[1] -= num6 * (array[1] - g) / NeuQuant.alpharadbias;
array[2] -= num6 * (array[2] - r) / NeuQuant.alpharadbias;
}
catch (Exception ex)
{
}
}
if (num4 > num)
{
int[] array = this.network[num4--];
try
{
array[0] -= num6 * (array[0] - b) / NeuQuant.alpharadbias;
array[1] -= num6 * (array[1] - g) / NeuQuant.alpharadbias;
array[2] -= num6 * (array[2] - r) / NeuQuant.alpharadbias;
}
catch (Exception ex2)
{
}
}
}
}
// Token: 0x06000052 RID: 82 RVA: 0x00004CE4 File Offset: 0x000030E4
protected void Altersingle(int alpha, int i, int b, int g, int r)
{
int[] array = this.network[i];
array[0] -= alpha * (array[0] - b) / NeuQuant.initalpha;
array[1] -= alpha * (array[1] - g) / NeuQuant.initalpha;
array[2] -= alpha * (array[2] - r) / NeuQuant.initalpha;
}
// Token: 0x06000053 RID: 83 RVA: 0x00004D48 File Offset: 0x00003148
protected int Contest(int b, int g, int r)
{
int num = int.MaxValue;
int num2 = num;
int num3 = -1;
int num4 = num3;
for (int i = 0; i < this.netsize; i++)
{
int[] array = this.network[i];
int num5 = array[0] - b;
if (num5 < 0)
{
num5 = -num5;
}
int num6 = array[1] - g;
if (num6 < 0)
{
num6 = -num6;
}
num5 += num6;
num6 = array[2] - r;
if (num6 < 0)
{
num6 = -num6;
}
num5 += num6;
if (num5 < num)
{
num = num5;
num3 = i;
}
int num7 = num5 - (this.bias[i] >> NeuQuant.intbiasshift - NeuQuant.netbiasshift);
if (num7 < num2)
{
num2 = num7;
num4 = i;
}
int num8 = this.freq[i] >> NeuQuant.betashift;
this.freq[i] -= num8;
this.bias[i] += num8 << NeuQuant.gammashift;
}
this.freq[num3] += NeuQuant.beta;
this.bias[num3] -= NeuQuant.betagamma;
return num4;
}
// Token: 0x0400006B RID: 107
protected int netsize;
// Token: 0x0400006C RID: 108
protected static readonly int prime1 = 499;
// Token: 0x0400006D RID: 109
protected static readonly int prime2 = 491;
// Token: 0x0400006E RID: 110
protected static readonly int prime3 = 487;
// Token: 0x0400006F RID: 111
protected static readonly int prime4 = 503;
// Token: 0x04000070 RID: 112
protected static readonly int minpicturebytes = 3 * NeuQuant.prime4;
// Token: 0x04000071 RID: 113
protected int maxnetpos;
// Token: 0x04000072 RID: 114
protected static readonly int netbiasshift = 4;
// Token: 0x04000073 RID: 115
protected static readonly int ncycles = 100;
// Token: 0x04000074 RID: 116
protected static readonly int intbiasshift = 16;
// Token: 0x04000075 RID: 117
protected static readonly int intbias = 1 << NeuQuant.intbiasshift;
// Token: 0x04000076 RID: 118
protected static readonly int gammashift = 10;
// Token: 0x04000077 RID: 119
protected static readonly int gamma = 1 << NeuQuant.gammashift;
// Token: 0x04000078 RID: 120
protected static readonly int betashift = 10;
// Token: 0x04000079 RID: 121
protected static readonly int beta = NeuQuant.intbias >> NeuQuant.betashift;
// Token: 0x0400007A RID: 122
protected static readonly int betagamma = NeuQuant.intbias << NeuQuant.gammashift - NeuQuant.betashift;
// Token: 0x0400007B RID: 123
protected int initrad;
// Token: 0x0400007C RID: 124
protected static readonly int radiusbiasshift = 6;
// Token: 0x0400007D RID: 125
protected static readonly int radiusbias = 1 << NeuQuant.radiusbiasshift;
// Token: 0x0400007E RID: 126
protected int initradius;
// Token: 0x0400007F RID: 127
protected static readonly int radiusdec = 30;
// Token: 0x04000080 RID: 128
protected static readonly int alphabiasshift = 10;
// Token: 0x04000081 RID: 129
protected static readonly int initalpha = 1 << NeuQuant.alphabiasshift;
// Token: 0x04000082 RID: 130
protected int alphadec;
// Token: 0x04000083 RID: 131
protected static readonly int radbiasshift = 8;
// Token: 0x04000084 RID: 132
protected static readonly int radbias = 1 << NeuQuant.radbiasshift;
// Token: 0x04000085 RID: 133
protected static readonly int alpharadbshift = NeuQuant.alphabiasshift + NeuQuant.radbiasshift;
// Token: 0x04000086 RID: 134
protected static readonly int alpharadbias = 1 << NeuQuant.alpharadbshift;
// Token: 0x04000087 RID: 135
protected byte[] thepicture;
// Token: 0x04000088 RID: 136
protected int lengthcount;
// Token: 0x04000089 RID: 137
protected int samplefac;
// Token: 0x0400008A RID: 138
protected int[][] network;
// Token: 0x0400008B RID: 139
protected int[] netindex = new int[256];
// Token: 0x0400008C RID: 140
protected int[] bias;
// Token: 0x0400008D RID: 141
protected int[] freq;
// Token: 0x0400008E RID: 142
protected int[] radpower;
}
}