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); }
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)); }