Garry1115 2018-04-09 08:44 采纳率: 0%
浏览 584
已结题

有木有C#大神 求这个(Decompressor)类的解释,如果用java应该怎样写呢?

internal class Decompressor
{
    public unsafe static byte[] decompress(byte[] src, int maxSize)
    {
        int dLen = maxSize;
        byte[] data;
        byte[] dstExt = new byte[dLen + 0x800];
        fixed (byte* s = src, d = dstExt)
        {
            if (DecompressData(s, src.Length, d, &dLen) == 0)
                throw new System.Exception();
            data = new byte[dLen];
            for (int i = 0; i < dLen; i++)
                data[i] = d[i];
        }
        return data;
    }

    unsafe static int DecompressData(byte* pSrc, int szSrc, byte* pDst, int* pszDst)
    {
        if ((pSrc == null) || (szSrc < 3) || (pDst == null) || (pszDst == null) || (*pszDst < 1))
            return 0;
        byte* pTo = pDst;
        byte* pEndSrc = &pSrc[szSrc];
        byte* pEndDst = &pDst[*pszDst];
        *pszDst = 0;
        if ((pEndSrc[-1] != 0) || (pEndSrc[-2] != 0) || (pEndSrc[-3] != 0x11))
            return 0;
        uint ch = *pSrc;
        if (ch > 0x11)
        {
            ch -= 0x11;
            pSrc++;
            if (ch < 4)
                goto LABEL_37;
            if ((pEndDst - pDst < ch) || (pEndSrc - pSrc < ch + 1))
                return 0;
            while (ch-- > 0)
                *pDst++ = *pSrc++;
            goto LABEL_31;
        }
    LABEL_15:
        ch = *pSrc++;
        if (ch >= 0x10)
            goto LABEL_41;
        if (ch == 0)
        {
            if (pSrc > pEndSrc)
                return 0;
            while (*pSrc == 0)
            {
                ch += 0xFF;
                if (++pSrc > pEndSrc)
                    return 0;
            }
            ch += (uint)*pSrc++ + 0xF;
        }
        if ((pEndDst - pDst < ch + 3) || (pEndSrc - pSrc < ch + 4))
            return 0;
        *(uint*)pDst = *(uint*)pSrc;
        pDst += 4;
        pSrc += 4;
        if (--ch != 0)
        {
            while (ch >= 4)
            {
                *(uint*)pDst = *(uint*)pSrc;
                pDst += 4;
                pSrc += 4;
                ch -= 4;
            }
        }
        while (ch-- > 0)
            *pDst++ = *pSrc++;
    LABEL_31:
        ch = *pSrc++;
        if (ch >= 0x10)
            goto LABEL_41;
        byte* p = pDst - (*pSrc++ * 4) - (ch / 4) - 0x801;
        if ((p < pTo) || (pEndDst - pDst < 3))
            return 0;
        *pDst++ = *p++;
        *pDst++ = *p++;
        *pDst++ = *p++;
    LABEL_36:
        ch = (uint)pSrc[-2] & 3;
        if (ch == 0)
            goto LABEL_15;
    LABEL_37:
        if ((pEndDst - pDst < ch) || (pEndSrc - pSrc < ch + 1))
            return 0;
        while (ch-- > 0)
            *pDst++ = *pSrc++;
        ch = *pSrc++;
    LABEL_41:
        if (ch >= 0x40)
        {
            p = pDst - (*pSrc++ * 8) - ((ch / 4) & 7) - 1;
            ch = ch / 32 - 1;
            if ((p < pTo) || (pEndDst - pDst < ch + 2))
                return 0;
            *pDst++ = *p++;
            *pDst++ = *p++;
            while (ch-- > 0)
                *pDst++ = *p++;
            goto LABEL_36;
        }
        if (ch >= 0x20)
        {
            ch &= 0x1F;
            if (ch == 0)
            {
                if (pSrc > pEndSrc)
                    return 0;
                while (*pSrc == 0)
                {
                    ch += 0xFF;
                    if (++pSrc > pEndSrc)
                        return 0;
                }
                ch += (uint)*pSrc++ + 0x1F;
            }
            p = pDst - (*(ushort*)pSrc / 4) - 1;
            pSrc += 2;
            if ((p < pTo) || (pEndDst - pDst < ch + 2))
                return 0;
            if ((ch >= 6) && (pDst - p >= 4))
            {
                *(uint*)pDst = *(uint*)p;
                pDst += 4;
                p += 4;
                ch -= 2;
                while (ch >= 4)
                {
                    *(uint*)pDst = *(uint*)p;
                    pDst += 4;
                    p += 4;
                    ch -= 4;
                }
            }
            else
            {
                *pDst++ = *p++;
                *pDst++ = *p++;
            }
            while (ch-- > 0)
                *pDst++ = *p++;
            goto LABEL_36;
        }
        if (ch >= 0x10)
        {
            p = pDst - ((ch & 8) << 11);
            ch &= 7;
            if (ch == 0)
            {
                if (pSrc > pEndSrc)
                    return 0;
                while (*pSrc == 0)
                {
                    ch += 0xFF;
                    if (++pSrc > pEndSrc)
                        return 0;
                }
                ch += (uint)*pSrc++ + 7;
            }
            p -= (*(ushort*)pSrc / 4);
            pSrc += 2;
            if (p == pDst)
            {
                *pszDst = (int)(pDst - pTo);
                return (pSrc == pEndSrc) ? 1 : 0;
            }
            p -= 0x4000;
            if ((p < pTo) || (pEndDst - pDst < ch + 2))
                return 0;
            if ((ch >= 6) && (pDst - p >= 4))
            {
                *(uint*)pDst = *(uint*)p;
                pDst += 4;
                p += 4;
                ch -= 2;
                while (ch >= 4)
                {
                    *(uint*)pDst = *(uint*)p;
                    pDst += 4;
                    p += 4;
                    ch -= 4;
                }
            }
            else
            {
                *pDst++ = *p++;
                *pDst++ = *p++;
            }
            while (ch-- > 0)
                *pDst++ = *p++;
            goto LABEL_36;
        }
        p = pDst - (*pSrc++ * 4) - (ch / 4) - 1;
        *pDst++ = *p++;
        *pDst++ = *p++;
        if ((p >= pTo) && (pEndDst - pDst >= 2))
            goto LABEL_36;
        return 0;
    }

    public unsafe static byte[] compress(byte[] src)
    {
        int sLen = src.Length;
        byte[] dstBuf = new byte[sLen];
        int dLen = 0;
        fixed (byte* s = src, d = dstBuf)
        {
            byte* p = d;
            if (sLen > 0xD)
            {
                sLen = CompressData(s, sLen, d, &dLen);
                p = d + dLen;
            }
            if (sLen > 0)
            {
                byte* pFrom = s + src.Length - sLen;
                if ((p == d) && (sLen <= 0xEE))
                    *p++ = (byte)(sLen + 0x11);
                else if (sLen <= 3)
                    p[-2] |= (byte)sLen;
                else if (sLen <= 0x12)
                    *p++ = (byte)(sLen - 3);
                else
                {
                    p++;
                    int cnt = sLen - 0x12;
                    if (cnt > 0xFF)
                    {
                        ulong lbl = 0x80808081 * (ulong)(cnt - 1);
                        int bl = (int)(lbl >> 39);
                        p += bl;
                        for (int i = 0; i < bl; i++)
                            cnt -= 0xFF;
                    }
                    *p++ = (byte)cnt;
                }
                for (int i = 0; i < sLen; i++)
                    *p++ = *pFrom++;
            }
            *p++ = 0x11;
            p += 2;
            dLen = (int)(p - d);
        }
        byte[] data = new byte[dLen];
        for (int i = 0; i < dLen; i++)
            data[i] = dstBuf[i];
        return data;
    }

    unsafe static int CompressData(byte* pSrc, int szSrc, byte* pDst, int* pszDst)
    {
        byte*[] PtrBuf = new byte*[0x4000];
        byte* pTo = pDst;
        byte* pFrom = pSrc + 4;
        byte* pStart = pSrc;
        byte* pEnd = pSrc + szSrc;
        while (true)
        {
            int index = (((((pFrom[3] << 6) ^ pFrom[2]) << 5) ^ pFrom[1]) << 5) ^ pFrom[0];
            index += index << 5;
            index = (index >> 5) & 0x3FFF;
            byte* pPtr = PtrBuf[index];
            if (pPtr < pSrc)
                goto nextStep;
            szSrc = (int)(pFrom - pPtr);
            if ((szSrc == 0) || (szSrc > 0xBFFF))
                goto nextStep;
            if ((szSrc > 0x800) && (pPtr[3] != pFrom[3]))
            {
                index &= 0x7FF;
                index ^= 0x201F;
                pPtr = PtrBuf[index];
                if (pPtr < pSrc)
                    goto nextStep;
                szSrc = (int)(pFrom - pPtr);
                if ((szSrc == 0) || (szSrc > 0xBFFF) || ((szSrc > 0x800) && (pPtr[3] != pFrom[3])))
                    goto nextStep;
            }
            if ((pPtr[0] != pFrom[0]) || (pPtr[1] != pFrom[1]) || (pPtr[2] != pFrom[2]))
                goto nextStep;
            PtrBuf[index] = pFrom;
            int look = (int)(pFrom - pStart);
            if (look != 0)
            {
                if (look <= 3)
                    pTo[-2] |= (byte)look;
                else if (look <= 0x12)
                    *pTo++ = (byte)(look - 3);
                else
                {
                    *pTo++ = 0;
                    int cnt = look - 0x12;
                    if (cnt > 0xFF)
                    {
                        ulong lbl = 0x80808081 * (ulong)(cnt - 1);
                        int bl = (int)(lbl >> 39);
                        pTo += bl;
                        for (int i = 0; i < bl; i++)
                            cnt -= 0xFF;
                    }
                    *pTo++ = (byte)cnt;
                }
                for (int i = 0; i < look; i++)
                    *pTo++ = *pStart++;
            }
            pFrom += 3;
            if ((*pFrom++ == pPtr[3]) && (*pFrom++ == pPtr[4]) && (*pFrom++ == pPtr[5]) &&
                (*pFrom++ == pPtr[6]) && (*pFrom++ == pPtr[7]) && (*pFrom++ == pPtr[8]))
            {
                pPtr += 9;
                while (pFrom < pEnd)
                {
                    if (*pPtr != *pFrom)
                        break;
                    pPtr++;
                    pFrom++;
                }
                look = (int)(pFrom - pStart);
                if (szSrc <= 0x4000)
                {
                    szSrc--;
                    if (look <= 0x21)
                        *pTo++ = (byte)((look - 2) | 0x20);
                    else
                    {
                        *pTo++ = 0x20;
                        int cnt = look - 0x21;
                        if (cnt > 0xFF)
                        {
                            ulong lbl = 0x80808081 * (ulong)(cnt - 1);
                            int bl = (int)(lbl >> 39);
                            pTo += bl;
                            for (int i = 0; i < bl; i++)
                                cnt -= 0xFF;
                        }
                        *pTo++ = (byte)cnt;
                    }
                }
                else
                {
                    szSrc -= 0x4000;
                    if (look <= 9)
                        *pTo++ = (byte)(((szSrc >> 11) & 8) | (look - 2) | 0x10);
                    else
                    {
                        *pTo++ = (byte)(((szSrc >> 11) & 8) | 0x10);
                        int cnt = look - 9;
                        if (cnt > 0xFF)
                        {
                            ulong lbl = 0x80808081 * (ulong)(cnt - 1);
                            int bl = (int)(lbl >> 39);
                            pTo += bl;
                            for (int i = 0; i < bl; i++)
                                cnt -= 0xFF;
                        }
                        *pTo++ = (byte)cnt;
                    }
                }
                *pTo++ = (byte)(szSrc << 2);
                *pTo++ = (byte)(szSrc >> 6);
            }
            else
            {
                look = (int)(--pFrom - pStart);
                if (szSrc <= 0x800)
                {
                    szSrc--;
                    *pTo++ = (byte)(((look + 7) << 5) | ((szSrc & 7) << 2));
                    *pTo++ = (byte)(szSrc >> 3);
                }
                else if (szSrc <= 0x4000)
                {
                    *pTo++ = (byte)((look - 2) | 0x20);
                    szSrc--;
                    *pTo++ = (byte)(szSrc << 2);
                    *pTo++ = (byte)(szSrc >> 6);
                }
                else
                {
                    szSrc -= 0x4000;
                    *pTo++ = (byte)(((szSrc >> 11) & 8) | (look - 2) | 0x10);
                    *pTo++ = (byte)(szSrc << 2);
                    *pTo++ = (byte)(szSrc >> 6);
                }
            }
            pStart = pFrom;
            goto checkEnd;
        nextStep:
            PtrBuf[index] = pFrom++;
        checkEnd:
            if (pFrom >= (pEnd - 0xD))
                break;
        }
        *pszDst = (int)(pTo - pDst);
        return (int)(pEnd - pStart);
    }
}
  • 写回答

2条回答 默认 最新

  • threenewbee 2018-04-09 13:54
    关注

    反编译的代码,不一定能正确转换,建议你直接用java以com方式调用。

    评论

报告相同问题?

悬赏问题

  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作
  • ¥15 求NPF226060磁芯的详细资料