Terraria v1.4.4.9
Terraria source code documentation
Loading...
Searching...
No Matches
DxtDecoder.cs
Go to the documentation of this file.
1using System;
2using Microsoft.Xna.Framework.Graphics.PackedVector;
3
5
6internal class DxtDecoder
7{
8 private const int EndianOffset0 = 0;
9
10 private const int EndianOffset1 = 1;
11
12 private int width;
13
14 private int height;
15
17
18 private Color[] colorPalette = new Color[4];
19
20 private byte[] alphaPalette = new byte[8];
21
22 public int PackedDataSize
23 {
24 get
25 {
26 int num = ((format == SurfaceFormat.Dxt1) ? 8 : 16);
27 int num2 = width / 4;
28 int num3 = height / 4;
29 return num * num2 * num3;
30 }
31 }
32
34 {
35 if (((uint)(width | height) & 3u) != 0)
36 {
37 throw new ArgumentException();
38 }
39 this.width = width;
40 this.height = height;
41 this.format = format;
42 }
43
44 public Color[] Decode(byte[] source)
45 {
46 Color[] result = new Color[width * height];
47 int num = 0;
48 for (int i = 0; i < height; i += 4)
49 {
50 for (int j = 0; j < width; j += 4)
51 {
52 int resultOffset = i * width + j;
53 switch (format)
54 {
55 case SurfaceFormat.Dxt1:
56 DecodeRgbBlock(source, num, result, resultOffset, isDxt1: true);
57 num += 8;
58 break;
59 case SurfaceFormat.Dxt3:
60 DecodeRgbBlock(source, num + 8, result, resultOffset, isDxt1: false);
61 DecodeExplicitAlphaBlock(source, num, result, resultOffset);
62 num += 16;
63 break;
64 case SurfaceFormat.Dxt5:
65 DecodeRgbBlock(source, num + 8, result, resultOffset, isDxt1: false);
66 DecodeInterpolatedAlphaBlock(source, num, result, resultOffset);
67 num += 16;
68 break;
69 }
70 }
71 }
72 return result;
73 }
74
75 private void DecodeRgbBlock(byte[] source, int sourceOffset, Color[] result, int resultOffset, bool isDxt1)
76 {
77 ushort num = Read16(source, sourceOffset);
78 ushort num2 = Read16(source, sourceOffset + 2);
79 ref Color reference = ref colorPalette[0];
80 Bgr565 bgr = new Bgr565
81 {
82 PackedValue = num
83 };
84 reference = new Color(bgr.ToVector3());
85 ref Color reference2 = ref colorPalette[1];
86 Bgr565 bgr2 = new Bgr565
87 {
88 PackedValue = num2
89 };
90 reference2 = new Color(bgr2.ToVector3());
91 if (num > num2 || !isDxt1)
92 {
93 ref Color reference3 = ref colorPalette[2];
94 reference3 = Color.Lerp(colorPalette[0], colorPalette[1], 1f / 3f);
95 ref Color reference4 = ref colorPalette[3];
96 reference4 = Color.Lerp(colorPalette[0], colorPalette[1], 2f / 3f);
97 }
98 else
99 {
100 ref Color reference5 = ref colorPalette[2];
101 reference5 = Color.Lerp(colorPalette[0], colorPalette[1], 0.5f);
102 ref Color reference6 = ref colorPalette[3];
103 reference6 = Color.Transparent;
104 }
105 uint num3 = Read32(source, sourceOffset + 4);
106 for (int i = 0; i < 4; i++)
107 {
108 for (int j = 0; j < 4; j++)
109 {
110 uint num4 = num3 & 3u;
111 num3 >>= 2;
112 ref Color reference7 = ref result[resultOffset + i * width + j];
113 reference7 = colorPalette[num4];
114 }
115 }
116 }
117
118 private void DecodeExplicitAlphaBlock(byte[] source, int sourceOffset, Color[] result, int resultOffset)
119 {
120 for (int i = 0; i < 4; i++)
121 {
122 ushort num = Read16(source, sourceOffset + i * 2);
123 for (int j = 0; j < 4; j++)
124 {
125 int num2 = num & 0xF;
126 num >>= 4;
127 result[resultOffset + i * width + j].A = (byte)(num2 * 255 / 15);
128 }
129 }
130 }
131
132 private void DecodeInterpolatedAlphaBlock(byte[] source, int sourceOffset, Color[] result, int resultOffset)
133 {
134 byte b = source[sourceOffset];
135 byte b2 = source[sourceOffset + 1];
136 alphaPalette[0] = b;
137 alphaPalette[1] = b2;
138 if (b > b2)
139 {
140 alphaPalette[2] = (byte)((6 * b + b2 + 3) / 7);
141 alphaPalette[3] = (byte)((5 * b + 2 * b2 + 3) / 7);
142 alphaPalette[4] = (byte)((4 * b + 3 * b2 + 3) / 7);
143 alphaPalette[5] = (byte)((3 * b + 4 * b2 + 3) / 7);
144 alphaPalette[6] = (byte)((2 * b + 5 * b2 + 3) / 7);
145 alphaPalette[7] = (byte)((b + 6 * b2 + 3) / 7);
146 }
147 else
148 {
149 alphaPalette[2] = (byte)((4 * b + b2 + 2) / 5);
150 alphaPalette[3] = (byte)((3 * b + 2 * b2 + 2) / 5);
151 alphaPalette[4] = (byte)((2 * b + 3 * b2 + 2) / 5);
152 alphaPalette[5] = (byte)((b + 4 * b2 + 2) / 5);
153 alphaPalette[6] = 0;
154 alphaPalette[7] = byte.MaxValue;
155 }
156 ulong num = Read48(source, sourceOffset + 2);
157 for (int i = 0; i < 4; i++)
158 {
159 for (int j = 0; j < 4; j++)
160 {
161 int num2 = (int)num & 7;
162 num >>= 3;
163 result[resultOffset + i * width + j].A = alphaPalette[num2];
164 }
165 }
166 }
167
168 private static ushort Read16(byte[] source, int offset)
169 {
170 return (ushort)(source[offset] | (source[offset + 1] << 8));
171 }
172
173 private static uint Read32(byte[] source, int offset)
174 {
175 return (uint)(Read16(source, offset) | (Read16(source, offset + 2) << 16));
176 }
177
178 private static ulong Read48(byte[] source, int offset)
179 {
180 return Read16(source, offset) | ((ulong)Read16(source, offset + 2) << 16) | ((ulong)Read16(source, offset + 4) << 32);
181 }
182}
static ulong Read48(byte[] source, int offset)
void DecodeExplicitAlphaBlock(byte[] source, int sourceOffset, Color[] result, int resultOffset)
static uint Read32(byte[] source, int offset)
DxtDecoder(int width, int height, SurfaceFormat format)
Definition DxtDecoder.cs:33
void DecodeRgbBlock(byte[] source, int sourceOffset, Color[] result, int resultOffset, bool isDxt1)
Definition DxtDecoder.cs:75
static ushort Read16(byte[] source, int offset)
void DecodeInterpolatedAlphaBlock(byte[] source, int sourceOffset, Color[] result, int resultOffset)
static Color Transparent
Definition Color.cs:76
static Color Lerp(Color value1, Color value2, float amount)
Definition Color.cs:491