improved Texture2D convert

This commit is contained in:
Perfare 2019-06-04 13:05:49 +08:00
parent 3441135b2f
commit 378840bc1b
9 changed files with 57 additions and 54 deletions

View File

@ -71,23 +71,6 @@ namespace AssetStudio
private int astcBlockWidth; private int astcBlockWidth;
private int astcBlockHeight; private int astcBlockHeight;
[DllImport("PVRTexLibWrapper.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern bool DecompressPVR(byte[] buffer, IntPtr bmp, int len);
[DllImport("TextureConverterWrapper.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern bool Ponvert(byte[] buffer, IntPtr bmp, int nWidth, int nHeight, int len, int type, int bmpsize, bool fixAlpha);
[DllImport("crunch.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern bool DecompressCRN(byte[] pSrc_file_data, int src_file_size, out IntPtr uncompressedData, out int uncompressedSize);
[DllImport("crunchunity.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern bool DecompressUnityCRN(byte[] pSrc_file_data, int src_file_size, out IntPtr uncompressedData, out int uncompressedSize);
[DllImport("texgenpack.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void Decode(int texturetype, byte[] texturedata, int width, int height, IntPtr bmp);
[DllImport("astc.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern bool decode_astc(byte[] data, int width, int height, int blockwidth, int blockheight, IntPtr bmp);
public Texture2DConverter(Texture2D m_Texture2D) public Texture2DConverter(Texture2D m_Texture2D)
{ {
@ -873,7 +856,7 @@ namespace AssetStudio
case TextureFormat.BC5: case TextureFormat.BC5:
case TextureFormat.BC6H: case TextureFormat.BC6H:
case TextureFormat.BC7: case TextureFormat.BC7:
bitmap = Texgenpack(); bitmap = TexgenPackDecode();
break; break;
case TextureFormat.DXT1Crunched: case TextureFormat.DXT1Crunched:
case TextureFormat.DXT5Crunched: case TextureFormat.DXT5Crunched:
@ -935,43 +918,41 @@ namespace AssetStudio
{ {
buff = image_data; buff = image_data;
} }
var hObject = GCHandle.Alloc(buff, GCHandleType.Pinned); var gch = GCHandle.Alloc(buff, GCHandleType.Pinned);
var pObject = hObject.AddrOfPinnedObject(); var imagePtr = gch.AddrOfPinnedObject();
var bitmap = new Bitmap(m_Width, m_Height, stride, PixelFormat.Format16bppRgb565, pObject); var bitmap = new Bitmap(m_Width, m_Height, stride, PixelFormat.Format16bppRgb565, imagePtr);
hObject.Free(); gch.Free();
return bitmap; return bitmap;
} }
private Bitmap PVRToBitmap(byte[] pvrdata) private Bitmap PVRToBitmap(byte[] pvrData)
{ {
var bitmap = new Bitmap(m_Width, m_Height); var imageBuff = new byte[m_Width * m_Height * 4];
var rect = new Rectangle(0, 0, m_Width, m_Height); var gch = GCHandle.Alloc(imageBuff, GCHandleType.Pinned);
var bmd = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var imagePtr = gch.AddrOfPinnedObject();
var len = Math.Abs(bmd.Stride) * bmd.Height; if (!NativeMethods.DecompressPVR(pvrData, imagePtr))
if (!DecompressPVR(pvrdata, bmd.Scan0, len))
{ {
bitmap.UnlockBits(bmd); gch.Free();
bitmap.Dispose();
return null; return null;
} }
bitmap.UnlockBits(bmd); var bitmap = new Bitmap(m_Width, m_Height, m_Width * 4, PixelFormat.Format32bppArgb, imagePtr);
gch.Free();
return bitmap; return bitmap;
} }
private Bitmap TextureConverter() private Bitmap TextureConverter()
{ {
var bitmap = new Bitmap(m_Width, m_Height); var imageBuff = new byte[m_Width * m_Height * 4];
var rect = new Rectangle(0, 0, m_Width, m_Height); var gch = GCHandle.Alloc(imageBuff, GCHandleType.Pinned);
var bmd = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var imagePtr = gch.AddrOfPinnedObject();
var len = Math.Abs(bmd.Stride) * bmd.Height;
var fixAlpha = glBaseInternalFormat == KTXHeader.GL_RED || glBaseInternalFormat == KTXHeader.GL_RG; var fixAlpha = glBaseInternalFormat == KTXHeader.GL_RED || glBaseInternalFormat == KTXHeader.GL_RG;
if (!Ponvert(image_data, bmd.Scan0, m_Width, m_Height, image_data_size, (int)q_format, len, fixAlpha)) if (!NativeMethods.Ponvert(image_data, image_data_size, m_Width, m_Height, (int)q_format, fixAlpha, imagePtr))
{ {
bitmap.UnlockBits(bmd); gch.Free();
bitmap.Dispose();
return null; return null;
} }
bitmap.UnlockBits(bmd); var bitmap = new Bitmap(m_Width, m_Height, m_Width * 4, PixelFormat.Format32bppArgb, imagePtr);
gch.Free();
return bitmap; return bitmap;
} }
@ -984,11 +965,11 @@ namespace AssetStudio
|| m_TextureFormat == TextureFormat.ETC_RGB4Crunched || m_TextureFormat == TextureFormat.ETC_RGB4Crunched
|| m_TextureFormat == TextureFormat.ETC2_RGBA8Crunched) || m_TextureFormat == TextureFormat.ETC2_RGBA8Crunched)
{ {
result = DecompressUnityCRN(image_data, image_data_size, out uncompressedData, out uncompressedSize); result = NativeMethods.DecompressUnityCRN(image_data, image_data_size, out uncompressedData, out uncompressedSize);
} }
else else
{ {
result = DecompressCRN(image_data, image_data_size, out uncompressedData, out uncompressedSize); result = NativeMethods.DecompressCRN(image_data, image_data_size, out uncompressedData, out uncompressedSize);
} }
if (result) if (result)
@ -1001,32 +982,54 @@ namespace AssetStudio
} }
} }
private Bitmap Texgenpack() private Bitmap TexgenPackDecode()
{ {
var bitmap = new Bitmap(m_Width, m_Height); var imageBuff = new byte[m_Width * m_Height * 4];
var rect = new Rectangle(0, 0, m_Width, m_Height); var gch = GCHandle.Alloc(imageBuff, GCHandleType.Pinned);
var bmd = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var imagePtr = gch.AddrOfPinnedObject();
Decode((int)texturetype, image_data, m_Width, m_Height, bmd.Scan0); NativeMethods.TexgenPackDecode(image_data, (int)texturetype, m_Width, m_Height, imagePtr);
bitmap.UnlockBits(bmd); var bitmap = new Bitmap(m_Width, m_Height, m_Width * 4, PixelFormat.Format32bppArgb, imagePtr);
gch.Free();
return bitmap; return bitmap;
} }
private Bitmap DecodeASTC() private Bitmap DecodeASTC()
{ {
var bitmap = new Bitmap(m_Width, m_Height); var imageBuff = new byte[m_Width * m_Height * 4];
var rect = new Rectangle(0, 0, m_Width, m_Height); var gch = GCHandle.Alloc(imageBuff, GCHandleType.Pinned);
var bmd = bitmap.LockBits(rect, ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb); var imagePtr = gch.AddrOfPinnedObject();
if (!decode_astc(image_data, m_Width, m_Height, astcBlockWidth, astcBlockHeight, bmd.Scan0)) if (!NativeMethods.DecodeASTC(image_data, m_Width, m_Height, astcBlockWidth, astcBlockHeight, imagePtr))
{ {
bitmap.UnlockBits(bmd); gch.Free();
bitmap.Dispose();
return null; return null;
} }
bitmap.UnlockBits(bmd); var bitmap = new Bitmap(m_Width, m_Height, m_Width * 4, PixelFormat.Format32bppArgb, imagePtr);
gch.Free();
return bitmap; return bitmap;
} }
} }
internal static class NativeMethods
{
[DllImport("PVRTexLibWrapper.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool DecompressPVR(byte[] data, IntPtr image);
[DllImport("TextureConverterWrapper.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool Ponvert(byte[] data, int dataSize, int width, int height, int type, bool fixAlpha, IntPtr image);
[DllImport("crunch.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool DecompressCRN(byte[] data, int dataSize, out IntPtr uncompressedData, out int uncompressedSize);
[DllImport("crunchunity.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool DecompressUnityCRN(byte[] data, int dataSize, out IntPtr uncompressedData, out int uncompressedSize);
[DllImport("texgenpack.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void TexgenPackDecode(byte[] data, int textureType, int width, int height, IntPtr image);
[DllImport("astc.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool DecodeASTC(byte[] data, int width, int height, int blockwidth, int blockheight, IntPtr image);
}
public static class KTXHeader public static class KTXHeader
{ {
public static byte[] IDENTIFIER = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A }; public static byte[] IDENTIFIER = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };