Exemplo n.º 1
0
        private byte[] BLZ_Code(byte[] rawBuffer, int rawLen, int best)
        {
            int flg     = 0;
            int posBest = 0;
            int posNext = 0;
            int posPost = 0;

            int pakTmp = 0;
            int rawTmp = rawLen;

            int pakLen = rawLen + (rawLen + 7) / 8 + 11;

            byte[] pakBuffer = new byte[pakLen];

            int rawNew = rawLen;

            // We don't do any of the checks here
            // Presume that we actually are using an arm9
            if (this.arm9)
            {
                rawNew -= 0x4000;
            }

            BlzCoder.BLZ_Invert(rawBuffer, 0, rawLen);

            int pak    = 0;
            int raw    = 0;
            int rawEnd = rawNew;

            int mask = 0;

            while (raw < rawEnd)
            {
                if ((mask = (int)((uint)mask >> BlzShift)) == 0)
                {
                    pakBuffer[flg = pak++] = 0;
                    mask = BlzMask;
                }

                SearchPair sl1     = BlzCoder.Search(posBest, rawBuffer, raw, rawEnd);
                int        lenBest = sl1.l;
                posBest = sl1.p;

                // LZ-CUE optimization start
                if (best == BlzBest)
                {
                    if (lenBest > BlzThreshold)
                    {
                        if (raw + lenBest < rawEnd)
                        {
                            raw += lenBest;
                            SearchPair sl2 = BlzCoder.Search(posNext, rawBuffer, raw,
                                                             rawEnd);
                            int lenNext = sl2.l;
                            posNext = sl2.p;
                            raw    -= lenBest - 1;
                            SearchPair sl3 = BlzCoder.Search(posPost, rawBuffer, raw,
                                                             rawEnd);
                            int lenPost = sl3.l;
                            posPost = sl3.p;
                            raw--;

                            if (lenNext <= BlzThreshold)
                            {
                                lenNext = 1;
                            }
                            if (lenPost <= BlzThreshold)
                            {
                                lenPost = 1;
                            }
                            if (lenBest + lenNext <= 1 + lenPost)
                            {
                                lenBest = 1;
                            }
                        }
                    }
                }
                // LZ-CUE optimization end
                pakBuffer[flg] = (byte)(pakBuffer[flg] << 1);
                if (lenBest > BlzThreshold)
                {
                    raw             += lenBest;
                    pakBuffer[flg]  |= 1;
                    pakBuffer[pak++] = (byte)((byte)((lenBest - (BlzThreshold + 1)) << 4) | ((uint)(posBest - 3) >> 8));
                    pakBuffer[pak++] = (byte)(posBest - 3);
                }
                else
                {
                    pakBuffer[pak++] = rawBuffer[raw++];
                }

                if (pak + rawLen - raw >= pakTmp + rawTmp)
                {
                    continue;
                }

                pakTmp = pak;
                rawTmp = rawLen - raw;
            }

            while ((mask > 0) && (mask != 1))
            {
                mask           = (int)((uint)mask >> BlzShift);
                pakBuffer[flg] = (byte)(pakBuffer[flg] << 1);
            }

            pakLen = pak;

            BlzCoder.BLZ_Invert(rawBuffer, 0, rawLen);
            BlzCoder.BLZ_Invert(pakBuffer, 0, pakLen);

            if (pakTmp == 0 || (rawLen + 4 < ((pakTmp + rawTmp + 3) & 0xFFFFFFFC) + 8))
            {
                pak    = 0;
                raw    = 0;
                rawEnd = rawLen;

                while (raw < rawEnd)
                {
                    pakBuffer[pak++] = rawBuffer[raw++];
                }

                while ((pak & 3) > 0)
                {
                    pakBuffer[pak++] = 0;
                }

                pakBuffer[pak++] = 0;
                pakBuffer[pak++] = 0;
                pakBuffer[pak++] = 0;
                pakBuffer[pak++] = 0;
            }
            else
            {
                byte[] tmp = new byte[rawTmp + pakTmp + 11];

                int len;
                for (len = 0; len < rawTmp; len++)
                {
                    tmp[len] = rawBuffer[len];
                }

                for (len = 0; len < pakTmp; len++)
                {
                    tmp[rawTmp + len] = pakBuffer[len + pakLen - pakTmp];
                }

                pakBuffer = tmp;
                pak       = rawTmp + pakTmp;

                int encLen = pakTmp;
                int hdrLen = 8;
                int incLen = rawLen - pakTmp - rawTmp;

                while ((pak & 3) > 0)
                {
                    pakBuffer[pak++] = 0xFF;
                    hdrLen++;
                }

                BlzCoder.WriteUnsigned(pakBuffer, pak, encLen + hdrLen);
                pak += 3;
                pakBuffer[pak++] = (byte)hdrLen;
                BlzCoder.WriteUnsigned(pakBuffer, pak, incLen - hdrLen);
                pak += 4;
            }
            this.newLen = pak;
            return(pakBuffer);
        }
Exemplo n.º 2
0
        private static BlzResult BLZ_Decode(byte[] data)
        {
            int rawLen, len;
            int encLen, decLen;
            int flags = 0;

            byte[] pakBuffer = BlzCoder.PrepareData(data);
            int    pakLen    = pakBuffer.Length - 3;

            int incLen = BitConverter.ToInt32(pakBuffer, pakLen - 4);

            if (incLen < 1)
            {
                Console.Write(", WARNING: not coded file!");
                encLen = 0;
                decLen = pakLen;
                pakLen = 0;
                rawLen = decLen;
            }
            else
            {
                if (pakLen < 8)
                {
                    Console.Write(Environment.NewLine + "File has a bad header" + Environment.NewLine);
                    return(null);
                }
                int hdrLen = pakBuffer[pakLen - 5];
                if (hdrLen < 8 || hdrLen > 0xB)
                {
                    Console.Write(Environment.NewLine + "Bad header length" + Environment.NewLine);
                    return(null);
                }
                if (pakLen <= hdrLen)
                {
                    Console.Write(Environment.NewLine + "Bad length" + Environment.NewLine);
                    return(null);
                }
                encLen = (int)(BitConverter.ToUInt32(pakBuffer, pakLen - 8) & 0x00FFFFFF);
                decLen = pakLen - encLen;
                pakLen = encLen - hdrLen;
                rawLen = decLen + encLen + incLen;
                if (rawLen > RawMaxim)
                {
                    Console.Write(Environment.NewLine + "Bad decoded length" + Environment.NewLine);
                    return(null);
                }
            }

            byte[] rawBuffer = new byte[rawLen];

            int pak    = 0;
            int raw    = 0;
            int pakEnd = decLen + pakLen;
            int rawEnd = rawLen;

            for (len = 0; len < decLen; len++)
            {
                rawBuffer[raw++] = pakBuffer[pak++];
            }

            BlzCoder.BLZ_Invert(pakBuffer, decLen, pakLen);

            int mask = 0;

            while (raw < rawEnd)
            {
                if ((mask = (int)((uint)mask >> BlzShift)) == 0)
                {
                    if (pak == pakEnd)
                    {
                        break;
                    }

                    flags = pakBuffer[pak++];
                    mask  = BlzMask;
                }

                if ((flags & mask) == 0)
                {
                    if (pak == pakEnd)
                    {
                        break;
                    }

                    rawBuffer[raw++] = pakBuffer[pak++];
                }
                else
                {
                    if (pak + 1 >= pakEnd)
                    {
                        break;
                    }

                    int pos = pakBuffer[pak++] << 8;
                    pos |= pakBuffer[pak++];
                    len  = (int)((uint)pos >> 12) + BlzThreshold + 1;
                    if (raw + len > rawEnd)
                    {
                        Console.Write(", WARNING: wrong decoded length!");
                        len = rawEnd - raw;
                    }
                    pos = (pos & 0xFFF) + 3;
                    while (len-- > 0)
                    {
                        int charHere = rawBuffer[raw - pos];
                        rawBuffer[raw++] = (byte)charHere;
                    }
                }
            }

            BlzCoder.BLZ_Invert(rawBuffer, decLen, rawLen - decLen);

            rawLen = raw;

            if (raw != rawEnd)
            {
                Console.Write(", WARNING: unexpected end of encoded file!");
            }

            return(new BlzResult(rawBuffer, rawLen));
        }