static int pvrtcDecompress(byte[] pCompressedData, ref Pixel32[] pDecompressedData, uint ui32Width, uint ui32Height, byte ui8Bpp) { uint ui32WordWidth = 4; uint ui32WordHeight = 4; if (ui8Bpp == 2) { ui32WordWidth = 8; } uint[] pWordMembers = new uint[pCompressedData.Length / 4]; for (int i = 0; i < pCompressedData.Length; i += 4) { pWordMembers[i / 4] = BitConverter.ToUInt32(pCompressedData, i); } int i32NumXWords = (int)(ui32Width / ui32WordWidth); int i32NumYWords = (int)(ui32Height / ui32WordHeight); PVRTCWordIndices indices; Pixel32[] pPixels = new Pixel32[ui32WordWidth * ui32WordHeight]; for (int wordY = -1; wordY < i32NumYWords - 1; wordY++) { for (int wordX = -1; wordX < i32NumXWords - 1; wordX++) { indices = new PVRTCWordIndices( (int)wrapWordIndex((uint)i32NumXWords, wordX), (int)wrapWordIndex((uint)i32NumYWords, wordY), (int)wrapWordIndex((uint)i32NumXWords, wordX + 1), (int)wrapWordIndex((uint)i32NumYWords, wordY), (int)wrapWordIndex((uint)i32NumXWords, wordX), (int)wrapWordIndex((uint)i32NumYWords, wordY + 1), (int)wrapWordIndex((uint)i32NumXWords, wordX + 1), (int)wrapWordIndex((uint)i32NumYWords, wordY + 1)); uint[] WordOffsets = new uint[4] { TwiddleUV((uint)i32NumXWords, (uint)i32NumYWords, (uint)indices.P[0], (uint)indices.P[1]) * 2, TwiddleUV((uint)i32NumXWords, (uint)i32NumYWords, (uint)indices.Q[0], (uint)indices.Q[1]) * 2, TwiddleUV((uint)i32NumXWords, (uint)i32NumYWords, (uint)indices.R[0], (uint)indices.R[1]) * 2, TwiddleUV((uint)i32NumXWords, (uint)i32NumYWords, (uint)indices.S[0], (uint)indices.S[1]) * 2, }; PVRTCWord P, Q, R, S; P.u32ColorData = pWordMembers[WordOffsets[0] + 1]; P.u32ModulationData = pWordMembers[WordOffsets[0]]; Q.u32ColorData = pWordMembers[WordOffsets[1] + 1]; Q.u32ModulationData = pWordMembers[WordOffsets[1]]; R.u32ColorData = pWordMembers[WordOffsets[2] + 1]; R.u32ModulationData = pWordMembers[WordOffsets[2]]; S.u32ColorData = pWordMembers[WordOffsets[3] + 1]; S.u32ModulationData = pWordMembers[WordOffsets[3]]; pvrtcGetDecompressedPixels(P, Q, R, S, ref pPixels, ui8Bpp); mapDecompressedData(ref pDecompressedData, (int)ui32Width, pPixels, indices, ui8Bpp); } } return((int)(ui32Width * ui32Height / (uint)(ui32WordWidth / 2))); }
static void mapDecompressedData(ref Pixel32[] pOutput, int width, Pixel32[] pWord, PVRTCWordIndices words, byte ui8Bpp) { uint ui32WordWidth = 4; uint ui32WordHeight = 4; if (ui8Bpp == 2) { ui32WordWidth = 8; } for (uint y = 0; y < ui32WordHeight / 2; y++) { for (uint x = 0; x < ui32WordWidth / 2; x++) { pOutput[(((words.P[1] * ui32WordHeight) + y + ui32WordHeight / 2) * width + words.P[0] * ui32WordWidth + x + ui32WordWidth / 2)] = pWord[y * ui32WordWidth + x]; pOutput[(((words.Q[1] * ui32WordHeight) + y + ui32WordHeight / 2) * width + words.Q[0] * ui32WordWidth + x)] = pWord[y * ui32WordWidth + x + ui32WordWidth / 2]; pOutput[(((words.R[1] * ui32WordHeight) + y) * width + words.R[0] * ui32WordWidth + x + ui32WordWidth / 2)] = pWord[(y + ui32WordHeight / 2) * ui32WordWidth + x]; pOutput[(((words.S[1] * ui32WordHeight) + y) * width + words.S[0] * ui32WordWidth + x)] = pWord[(y + ui32WordHeight / 2) * ui32WordWidth + x + ui32WordWidth / 2]; } } }