返回提交历史
Deleted
SpaceEngineersBlueprintEditor.ImageLibrary/DxtUtil.cs
+0
-1274
Deleted
SpaceEngineersBlueprintEditor.ImageLibrary/ImageTextureUtil.cs
+0
-488
Deleted
SpaceEngineersBlueprintEditor.ImageLibrary/SpaceEngineersBlueprintEditor.ImageLibrary.csproj
+0
-10
SpaceEngineersModDev/SpaceEngineersBlueprintEditorInWinUI
删除多余的项目
12f1098
代码差异
3 个文件
+0
-1772
@@ -1,488 +0,0 @@
1
namespace SpaceEngineersBlueprintEditor.ImageLibrary;
2
3
using System;
4
using System.Drawing;
5
using System.Drawing.Imaging;
6
using System.IO;
7
using System.Runtime.InteropServices;
8
9
/// <summary>
10
/// A cobbled togeather utility for reading the Space Engineers texture assets which are generally defined as BC3_UNorm textures in .dds files.
11
/// </summary>
12
public static class ImageTextureUtil
13
{
14
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb943991(v=vs.85).aspx#File_Layout1
15
// http://msdn.microsoft.com/en-us/library/windows/apps/jj651550.aspx
16
17
#region const
18
19
/// <summary>
20
/// PixelFormat flags.
21
/// </summary>
22
[Flags]
23
public enum PixelFormatFlags
24
{
25
FourCC = 0x00000004, // DDPF_FOURCC
26
Rgb = 0x00000040, // DDPF_RGB
27
Rgba = 0x00000041, // DDPF_RGB | DDPF_ALPHAPIXELS
28
Luminance = 0x00020000, // DDPF_LUMINANCE
29
LuminanceAlpha = 0x00020001, // DDPF_LUMINANCE | DDPF_ALPHAPIXELS
30
Alpha = 0x00000002, // DDPF_ALPHA
31
Pal8 = 0x00000020, // DDPF_PALETTEINDEXED8
32
}
33
34
#endregion
35
36
#region enums
37
38
[Flags]
39
internal enum DDSCAPS2 : uint
40
{
41
DDSCAPS2_CUBEMAP = 0x200,
42
DDSCAPS2_CUBEMAP_POSITIVEX = 0x400,
43
DDSCAPS2_CUBEMAP_NEGATIVEX = 0x800,
44
DDSCAPS2_CUBEMAP_POSITIVEY = 0x1000,
45
DDSCAPS2_CUBEMAP_NEGATIVEY = 0x2000,
46
DDSCAPS2_CUBEMAP_POSITIVEZ = 0x4000,
47
DDSCAPS2_CUBEMAP_NEGATIVEZ = 0x8000,
48
DDSCAPS2_VOLUME = 0x200000,
49
}
50
51
internal enum DDSType
52
{
53
DDS_A8R8G8B8 = 0,
54
DDS_A1R5G5B5 = 1,
55
DDS_A4R4G4B4 = 2,
56
DDS_R8G8B8 = 3,
57
DDS_R5G6B5 = 4,
58
DDS_DXT1 = 5,
59
DDS_DXT2 = 6,
60
DDS_DXT3 = 7,
61
DDS_DXT4 = 8,
62
DDS_DXT5 = 9,
63
DDS_RXGB = 10,
64
DDS_ATI2 = 11,
65
DDS_UNKNOWN
66
}
67
68
internal enum DDS_FOURCC : uint
69
{
70
DXT1 = 0x31545844,
71
DXT3 = 0x33545844,
72
DXT5 = 0x35545844,
73
BC4U = 0x55344342,
74
BC4S = 0x53344342,
75
ATI2 = 0x32495441,
76
BC5S = 0x53354342,
77
RGBG = 0x47424752,
78
GRGB = 0x42475247,
79
DXT2 = 0x32545844,
80
DXT4 = 0x34545844,
81
UYVY = 0x59565955,
82
YUY2 = 0x32595559,
83
DX10 = 0x30315844,
84
};
85
86
public enum DXGI_FORMAT : uint
87
{
88
DXGI_FORMAT_UNKNOWN = 0,
89
DXGI_FORMAT_R32G32B32A32_TYPELESS = 1,
90
DXGI_FORMAT_R32G32B32A32_FLOAT = 2,
91
DXGI_FORMAT_R32G32B32A32_UINT = 3,
92
DXGI_FORMAT_R32G32B32A32_SINT = 4,
93
DXGI_FORMAT_R32G32B32_TYPELESS = 5,
94
DXGI_FORMAT_R32G32B32_FLOAT = 6,
95
DXGI_FORMAT_R32G32B32_UINT = 7,
96
DXGI_FORMAT_R32G32B32_SINT = 8,
97
DXGI_FORMAT_R16G16B16A16_TYPELESS = 9,
98
DXGI_FORMAT_R16G16B16A16_FLOAT = 10,
99
DXGI_FORMAT_R16G16B16A16_UNORM = 11,
100
DXGI_FORMAT_R16G16B16A16_UINT = 12,
101
DXGI_FORMAT_R16G16B16A16_SNORM = 13,
102
DXGI_FORMAT_R16G16B16A16_SINT = 14,
103
DXGI_FORMAT_R32G32_TYPELESS = 15,
104
DXGI_FORMAT_R32G32_FLOAT = 16,
105
DXGI_FORMAT_R32G32_UINT = 17,
106
DXGI_FORMAT_R32G32_SINT = 18,
107
DXGI_FORMAT_R32G8X24_TYPELESS = 19,
108
DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20,
109
DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21,
110
DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22,
111
DXGI_FORMAT_R10G10B10A2_TYPELESS = 23,
112
DXGI_FORMAT_R10G10B10A2_UNORM = 24,
113
DXGI_FORMAT_R10G10B10A2_UINT = 25,
114
DXGI_FORMAT_R11G11B10_FLOAT = 26,
115
DXGI_FORMAT_R8G8B8A8_TYPELESS = 27,
116
DXGI_FORMAT_R8G8B8A8_UNORM = 28,
117
DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29,
118
DXGI_FORMAT_R8G8B8A8_UINT = 30,
119
DXGI_FORMAT_R8G8B8A8_SNORM = 31,
120
DXGI_FORMAT_R8G8B8A8_SINT = 32,
121
DXGI_FORMAT_R16G16_TYPELESS = 33,
122
DXGI_FORMAT_R16G16_FLOAT = 34,
123
DXGI_FORMAT_R16G16_UNORM = 35,
124
DXGI_FORMAT_R16G16_UINT = 36,
125
DXGI_FORMAT_R16G16_SNORM = 37,
126
DXGI_FORMAT_R16G16_SINT = 38,
127
DXGI_FORMAT_R32_TYPELESS = 39,
128
DXGI_FORMAT_D32_FLOAT = 40,
129
DXGI_FORMAT_R32_FLOAT = 41,
130
DXGI_FORMAT_R32_UINT = 42,
131
DXGI_FORMAT_R32_SINT = 43,
132
DXGI_FORMAT_R24G8_TYPELESS = 44,
133
DXGI_FORMAT_D24_UNORM_S8_UINT = 45,
134
DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46,
135
DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47,
136
DXGI_FORMAT_R8G8_TYPELESS = 48,
137
DXGI_FORMAT_R8G8_UNORM = 49,
138
DXGI_FORMAT_R8G8_UINT = 50,
139
DXGI_FORMAT_R8G8_SNORM = 51,
140
DXGI_FORMAT_R8G8_SINT = 52,
141
DXGI_FORMAT_R16_TYPELESS = 53,
142
DXGI_FORMAT_R16_FLOAT = 54,
143
DXGI_FORMAT_D16_UNORM = 55,
144
DXGI_FORMAT_R16_UNORM = 56,
145
DXGI_FORMAT_R16_UINT = 57,
146
DXGI_FORMAT_R16_SNORM = 58,
147
DXGI_FORMAT_R16_SINT = 59,
148
DXGI_FORMAT_R8_TYPELESS = 60,
149
DXGI_FORMAT_R8_UNORM = 61,
150
DXGI_FORMAT_R8_UINT = 62,
151
DXGI_FORMAT_R8_SNORM = 63,
152
DXGI_FORMAT_R8_SINT = 64,
153
DXGI_FORMAT_A8_UNORM = 65,
154
DXGI_FORMAT_R1_UNORM = 66,
155
DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67,
156
DXGI_FORMAT_R8G8_B8G8_UNORM = 68,
157
DXGI_FORMAT_G8R8_G8B8_UNORM = 69,
158
DXGI_FORMAT_BC1_TYPELESS = 70,
159
DXGI_FORMAT_BC1_UNORM = 71,
160
DXGI_FORMAT_BC1_UNORM_SRGB = 72,
161
DXGI_FORMAT_BC2_TYPELESS = 73,
162
DXGI_FORMAT_BC2_UNORM = 74,
163
DXGI_FORMAT_BC2_UNORM_SRGB = 75,
164
DXGI_FORMAT_BC3_TYPELESS = 76,
165
DXGI_FORMAT_BC3_UNORM = 77,
166
DXGI_FORMAT_BC3_UNORM_SRGB = 78,
167
DXGI_FORMAT_BC4_TYPELESS = 79,
168
DXGI_FORMAT_BC4_UNORM = 80,
169
DXGI_FORMAT_BC4_SNORM = 81,
170
DXGI_FORMAT_BC5_TYPELESS = 82,
171
DXGI_FORMAT_BC5_UNORM = 83,
172
DXGI_FORMAT_BC5_SNORM = 84,
173
DXGI_FORMAT_B5G6R5_UNORM = 85,
174
DXGI_FORMAT_B5G5R5A1_UNORM = 86,
175
DXGI_FORMAT_B8G8R8A8_UNORM = 87,
176
DXGI_FORMAT_B8G8R8X8_UNORM = 88,
177
DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89,
178
DXGI_FORMAT_B8G8R8A8_TYPELESS = 90,
179
DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91,
180
DXGI_FORMAT_B8G8R8X8_TYPELESS = 92,
181
DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93,
182
DXGI_FORMAT_BC6H_TYPELESS = 94,
183
DXGI_FORMAT_BC6H_UF16 = 95,
184
DXGI_FORMAT_BC6H_SF16 = 96,
185
DXGI_FORMAT_BC7_TYPELESS = 97,
186
DXGI_FORMAT_BC7_UNORM = 98,
187
DXGI_FORMAT_BC7_UNORM_SRGB = 99,
188
DXGI_FORMAT_AYUV = 100,
189
DXGI_FORMAT_Y410 = 101,
190
DXGI_FORMAT_Y416 = 102,
191
DXGI_FORMAT_NV12 = 103,
192
DXGI_FORMAT_P010 = 104,
193
DXGI_FORMAT_P016 = 105,
194
DXGI_FORMAT_420_OPAQUE = 106,
195
DXGI_FORMAT_YUY2 = 107,
196
DXGI_FORMAT_Y210 = 108,
197
DXGI_FORMAT_Y216 = 109,
198
DXGI_FORMAT_NV11 = 110,
199
DXGI_FORMAT_AI44 = 111,
200
DXGI_FORMAT_IA44 = 112,
201
DXGI_FORMAT_P8 = 113,
202
DXGI_FORMAT_A8P8 = 114,
203
DXGI_FORMAT_B4G4R4A4_UNORM = 115,
204
//DXGI_FORMAT_FORCE_UINT = 0xffffffffUL
205
};
206
207
internal enum D3D10_RESOURCE_DIMENSION : uint
208
{
209
D3D10_RESOURCE_DIMENSION_UNKNOWN = 0,
210
D3D10_RESOURCE_DIMENSION_BUFFER = 1,
211
D3D10_RESOURCE_DIMENSION_TEXTURE1D = 2,
212
D3D10_RESOURCE_DIMENSION_TEXTURE2D = 3,
213
D3D10_RESOURCE_DIMENSION_TEXTURE3D = 4
214
};
215
216
#endregion
217
218
#region structs
219
220
[StructLayout(LayoutKind.Sequential)]
221
internal struct DDS_PIXELFORMAT
222
{
223
internal UInt32 dwSize;
224
internal UInt32 dwFlags;
225
internal UInt32 dwFourCC;
226
internal UInt32 dwRGBBitCount;
227
internal UInt32 dwRBitMask;
228
internal UInt32 dwGBitMask;
229
internal UInt32 dwBBitMask;
230
internal UInt32 dwABitMask;
231
};
232
233
[StructLayout(LayoutKind.Sequential)]
234
internal unsafe struct DDS_HEADER
235
{
236
internal UInt32 dwSize;
237
internal UInt32 dwFlags;
238
internal UInt32 dwHeight;
239
internal UInt32 dwWidth;
240
internal UInt32 dwPitchOrLinearSize;
241
internal UInt32 dwDepth;
242
internal UInt32 dwMipMapCount;
243
internal fixed UInt32 dwReserved1[11];
244
internal DDS_PIXELFORMAT ddspf;
245
internal UInt32 dwCaps;
246
internal UInt32 dwCaps2;
247
internal UInt32 dwCaps3;
248
internal UInt32 dwCaps4;
249
internal UInt32 dwReserved2;
250
251
/// <summary>
252
/// The size of the <see cref="DDS_HEADER"/> type, in bytes.
253
/// </summary>
254
public static readonly int SizeInBytes = Marshal.SizeOf(typeof(DDS_HEADER));
255
};
256
257
[StructLayout(LayoutKind.Sequential)]
258
internal struct DDS_HEADER_DXT10
259
{
260
internal DXGI_FORMAT dxgiFormat;
261
internal D3D10_RESOURCE_DIMENSION resourceDimension;
262
internal uint miscFlag;
263
internal uint arraySize;
264
internal uint miscFlags2;
265
266
/// <summary>
267
/// The size of the <see cref="DDS_HEADER"/> type, in bytes.
268
/// </summary>
269
public static readonly int SizeInBytes = Marshal.SizeOf(typeof(DDS_HEADER_DXT10));
270
};
271
272
#endregion
273
274
#region MarshalTo
275
276
private static T MarshalTo<T>(byte[] buffer)
277
{
278
IntPtr intPtr = Marshal.AllocHGlobal(buffer.Length);
279
Marshal.Copy(buffer, 0, intPtr, buffer.Length);
280
var record = (T)Marshal.PtrToStructure(intPtr, typeof(T));
281
Marshal.FreeHGlobal(intPtr);
282
return record;
283
}
284
285
#endregion
286
287
#region CreateBitmap
288
289
internal static Bitmap DecompressTextureToBitmap(byte[] imageData, int width, int height, bool ignoreAlpha, uint fourCC, ImageTextureUtil.DXGI_FORMAT dxgiFormat)
290
{
291
using (var imageStream = new MemoryStream(imageData))
292
{
293
byte[] pixelColors;
294
295
if (fourCC == (uint)ImageTextureUtil.DDS_FOURCC.DXT1)
296
pixelColors = DxtUtil.DecompressDxt1(imageStream, width, height);
297
else if (fourCC == (uint)ImageTextureUtil.DDS_FOURCC.DXT3)
298
pixelColors = DxtUtil.DecompressDxt3(imageStream, width, height);
299
else
300
pixelColors = DxtUtil.DecompressDxt5(imageStream, width, height, dxgiFormat);
301
302
// Copy the pixel colors into a byte array
303
const int bytesPerPixel = 4;
304
var pixelRgba = new byte[pixelColors.Length];
305
for (var i = 0; i < pixelColors.Length; i += bytesPerPixel)
306
{
307
pixelRgba[i + 0] = pixelColors[i + 2];
308
pixelRgba[i + 1] = pixelColors[i + 1];
309
pixelRgba[i + 2] = pixelColors[i + 0];
310
pixelRgba[i + 3] = ignoreAlpha ? (byte)0xff : pixelColors[i + 3];
311
}
312
313
// Here create the Bitmap to the know height, width and format
314
var bmp = new Bitmap(width, height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
315
316
// Create a BitmapData and Lock all pixels to be written
317
var bmpData = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, bmp.PixelFormat);
318
319
//Copy the data from the byte array into BitmapData.Scan0
320
Marshal.Copy(pixelRgba, 0, bmpData.Scan0, pixelRgba.Length);
321
322
// Unlock the pixels
323
bmp.UnlockBits(bmpData);
324
325
return bmp;
326
}
327
}
328
329
public static Bitmap CreateBitmap(Stream stream, int depthSlice = 0, int width = -1, int height = -1, bool ignoreAlpha = false)
330
{
331
if (stream == null)
332
return null;
333
uint fourCC = 0;
334
DXGI_FORMAT dxgiFormat;
335
var pixelChannel = ReadTextureFile(stream, depthSlice, ref width, ref height, out fourCC, out dxgiFormat);
336
if (pixelChannel == null)
337
return null;
338
try
339
{
340
return DecompressTextureToBitmap(pixelChannel, width, height, ignoreAlpha, fourCC, dxgiFormat);
341
}
342
catch
343
{
344
return null;
345
}
346
}
347
348
#endregion
349
350
#region ReadTextureFile
351
352
public static byte[] ReadTextureFile(Stream stream, int depthSlice, ref int width, ref int height, out uint fourCC, out DXGI_FORMAT dxgiFormat)
353
{
354
dxgiFormat = DXGI_FORMAT.DXGI_FORMAT_UNKNOWN;
355
356
var reader = new BinaryReader(stream);
357
try
358
{
359
var magicNumber = reader.ReadUInt32();
360
if (magicNumber != 0x20534444)
361
{
362
fourCC = 0;
363
return null;
364
}
365
366
var header = MarshalTo<DDS_HEADER>(reader.ReadBytes(DDS_HEADER.SizeInBytes));
367
fourCC = header.ddspf.dwFourCC;
368
369
UInt32 bytesPerPixel;
370
UInt32 dwPitchOrLinearSize;
371
372
var slices = 1;
373
if (((DDSCAPS2)header.dwCaps2 & DDSCAPS2.DDSCAPS2_CUBEMAP) != 0)
374
slices = 6;
375
376
bytesPerPixel = header.dwPitchOrLinearSize / (header.dwWidth * header.dwHeight);
377
378
var c = header.dwCaps2;
379
var mipCount = (int)header.dwMipMapCount;
380
if (mipCount == 0)
381
mipCount = 1;
382
383
if (header.ddspf.dwFlags == (uint)PixelFormatFlags.FourCC && fourCC == (uint)DDS_FOURCC.DX10)
384
{
385
DDS_HEADER_DXT10 dx10Header = MarshalTo<DDS_HEADER_DXT10>(reader.ReadBytes(DDS_HEADER_DXT10.SizeInBytes));
386
dxgiFormat = dx10Header.dxgiFormat;
387
388
switch (dx10Header.dxgiFormat)
389
{
390
case DXGI_FORMAT.DXGI_FORMAT_BC1_TYPELESS:
391
case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM:
392
case DXGI_FORMAT.DXGI_FORMAT_BC1_UNORM_SRGB:
393
case DXGI_FORMAT.DXGI_FORMAT_BC2_TYPELESS:
394
case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM:
395
case DXGI_FORMAT.DXGI_FORMAT_BC2_UNORM_SRGB:
396
case DXGI_FORMAT.DXGI_FORMAT_BC3_TYPELESS:
397
case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM:
398
case DXGI_FORMAT.DXGI_FORMAT_BC3_UNORM_SRGB:
399
case DXGI_FORMAT.DXGI_FORMAT_BC4_TYPELESS:
400
case DXGI_FORMAT.DXGI_FORMAT_BC4_UNORM:
401
case DXGI_FORMAT.DXGI_FORMAT_BC4_SNORM:
402
case DXGI_FORMAT.DXGI_FORMAT_BC5_TYPELESS:
403
case DXGI_FORMAT.DXGI_FORMAT_BC5_UNORM:
404
case DXGI_FORMAT.DXGI_FORMAT_BC5_SNORM:
405
case DXGI_FORMAT.DXGI_FORMAT_BC6H_TYPELESS:
406
case DXGI_FORMAT.DXGI_FORMAT_BC6H_UF16:
407
case DXGI_FORMAT.DXGI_FORMAT_BC6H_SF16:
408
case DXGI_FORMAT.DXGI_FORMAT_BC7_TYPELESS:
409
case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM:
410
case DXGI_FORMAT.DXGI_FORMAT_BC7_UNORM_SRGB:
411
// The block-size is 8 bytes for DXT1, BC1, and BC4 formats, and 16 bytes for other block-compressed formats.
412
UInt32 blockSize = 8;
413
// For block-compressed formats, compute the pitch as:
414
dwPitchOrLinearSize = Math.Max(1, ((header.dwWidth + 3) / 4)) * blockSize;
415
break;
416
417
case DXGI_FORMAT.DXGI_FORMAT_R8G8_B8G8_UNORM:
418
case DXGI_FORMAT.DXGI_FORMAT_G8R8_G8B8_UNORM:
419
//For R8G8_B8G8, G8R8_G8B8, legacy UYVY-packed, and legacy YUY2-packed formats, compute the pitch as:
420
dwPitchOrLinearSize = ((header.dwWidth + 1) >> 1) * 4;
421
break;
422
423
default:
424
//case DXGI_FORMAT.DXGI_FORMAT_R8G8B8A8_UNORM_SRGB:
425
// For other formats, compute the pitch as:
426
bytesPerPixel = header.ddspf.dwSize;
427
dwPitchOrLinearSize = (header.dwWidth * bytesPerPixel + 7) / 8;
428
break;
429
}
430
//bytesPerPixel = BitsPerPixel(dx10Header.dxgiFormat);
431
}
432
433
if (bytesPerPixel == 0)
434
{
435
width = (int)header.dwWidth;
436
height = (int)header.dwHeight;
437
int size = (int)(reader.BaseStream.Length - reader.BaseStream.Position);
438
return reader.ReadBytes(size);
439
}
440
441
for (var slice = 0; slice < slices; slice++)
442
{
443
uint w = header.dwWidth == 0 ? 1 : header.dwWidth;
444
uint h = header.dwHeight == 0 ? 1 : header.dwHeight;
445
446
for (var map = 0; map < mipCount; map++)
447
{
448
var size = (int)(bytesPerPixel * w * h);
449
if (depthSlice == slice && ((width <= 0 && height <= 0) || (w == width && h == height)))
450
{
451
width = (int)w;
452
height = (int)h;
453
return reader.ReadBytes(size);
454
}
455
else
456
{
457
if (stream.CanSeek)
458
{
459
reader.BaseStream.Seek(size, SeekOrigin.Current);
460
}
461
else
462
{
463
// hack for VRage.Compression.MyStreamWrapper
464
for (int i = 0; i < size; i++)
465
reader.BaseStream.ReadByte();
466
}
467
}
468
469
w = w >> 1;
470
h = h >> 1;
471
if (w == 0) w = 1;
472
if (h == 0) h = 1;
473
}
474
475
reader.BaseStream.Seek(27, SeekOrigin.Current);
476
}
477
478
return null;
479
}
480
catch
481
{
482
fourCC = 0;
483
return null;
484
}
485
}
486
487
#endregion
488
}
@@ -1,10 +0,0 @@
1
<Project Sdk="Microsoft.NET.Sdk">
2
3
<!--This project is part of the SEToolBox.ImageLibrary-->
4
<PropertyGroup>
5
<TargetFramework>net48</TargetFramework>
6
<LangVersion>latest</LangVersion>
7
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
8
</PropertyGroup>
9
10
</Project>