正在解压缩PVRTC

Decompressing PVRTC

本文关键字:PVRTC 解压缩      更新时间:2023-10-16

任务

对于我自己的OpenGL Framework,当平台不支持PVRTC纹理时,我试图对其进行解压缩。为此,我下载了PVRTC-SDK,并将C++代码1:1翻译为带有非托管代码的C#代码。

问题

简而言之:它不起作用,我不知道原因。我已经检查了两次代码,它似乎还可以,应该可以工作有时我得到AccessViolationException,有时得到LoaderLockAccessViolationException不再出现,这是我代码的另一部分中的错误。PVRTC的颜色仍然错误。看起来很奇怪,基本笔画是可见的,但颜色不对。

代码

由于代码巨大的原因,我上传了它:

[C#]http://codeviewer.org/view/code:2a65

[C++]http://codeviewer.org/view/code:2a66

同样是C#方法的调用代码,大小实际上与预期值匹配(因此源数组的图像值正好是width * height * 4bit,输出大小是width * height * 4byte(因此压缩图像的8x大小)。

private static unsafe Image ConvertPVRTC_RGBA8888(Image source)
{
Int32 mipmapCount = source.HasMipmaps ? Image.GetMipmapCount(source.Width, source.Height) : 1;
// Create a array with bytes for the target format
Byte[] bytes = new Byte[RGBA8.GetMipMappedSize(0, mipmapCount, source.Width, source.Height)];

fixed (Byte* pTarget = bytes)
{
fixed (Byte* pSource = source.GetData())
{
Int32 sourceOffset = 0;
Int32 targetOffset = 0;
for (Int32 i = 0; i < mipmapCount; i++)
{
// Calculate offsets
Int32 sourceSize = source.Format.GetMipMappedSize(i, 1, source.Width, source.Height);
Int32 targetSize = RGBA8.GetMipMappedSize(i, 1, source.Width, source.Height);
// Decompress mipmapLevel
PVRTC.DecompressPVRTC(pSource + sourceOffset, pTarget + targetOffset, GetMipmapSize(source.Width, i), GetMipmapSize(source.Height, i), source.Format.BitsPerPixel == 2);
// Calculate pointer offset
sourceOffset += sourceSize;
targetOffset += targetSize;
}
}
}
return new Image(bytes, ImageFormat.RGBA8, source.Width, source.Height, source.HasMipmaps, source.IsCubemap);
}

思想

要么原始源代码不正确,要么我在翻译代码时遗漏了一些内容。无论如何,我需要一个解决方案,并检查了两次源代码。

(如果C#有任何源代码,我会使用它,但我找不到任何)

分治

在翻译代码的情况下,我建议对代码进行增量测试。如果你能为相同的代码段提供相同的数据(从最简单的方法开始),你就能确定问题出在哪里

类型大小

请注意,C#中的long可能与C++中的long不同。请注意,我还没有查看您的代码,看看这是否是您的情况下的问题(工作量太大)。

呼叫约定

在.NET中调用不安全的代码时,可能必须指定调用方法(如何将参数推送到堆栈上和从堆栈中删除)。在纯.NET解决方案中,我们不必担心这些问题,因为它们都是一样的。