public BlzCoder(IReadOnlyList <string> args) { int cmd, mode = 0; // Title(); if (args == null || (args.Count != 2)) { throw new Exception("No arguments supplied to BLZ"); } if (args[0].Equals("-d")) { cmd = CmdDecode; } else if (args[0].Equals("-en") || args[0].Equals("-en9")) { cmd = CmdEncode; mode = BlzNormal; } else if (args[0].Equals("-eo") || args[0].Equals("-eo9")) { cmd = CmdEncode; mode = BlzBest; } else { Console.Write("Command not supported" + Environment.NewLine); return; } if (args.Count < 2) { Console.Write("Filename not specified" + Environment.NewLine); } else { int arg; switch (cmd) { case 0: for (arg = 1; arg < args.Count; arg++) { BlzCoder.BLZ_Decode(args[arg]); } break; case 1: this.arm9 = args[0].Length > 3 && args[0][3] == '9'; for (arg = 1; arg < args.Count; arg++) { this.BLZ_Encode(args[arg], mode); } break; } } Console.Write(Environment.NewLine + "Done" + Environment.NewLine); }
private BlzResult BLZ_Encode(byte[] data, int mode) { this.newLen = 0; byte[] rawBuffer = BlzCoder.PrepareData(data); int rawLen = rawBuffer.Length - 3; byte[] pakBuffer = null; int pakLen = BlzMaxim + 1; byte[] newBuffer = this.BLZ_Code(rawBuffer, rawLen, mode); if (this.newLen < pakLen) { pakBuffer = newBuffer; pakLen = this.newLen; } return(new BlzResult(pakBuffer, pakLen)); }
private static void BLZ_Decode(string filename) { try { Console.Write($"- decoding '{filename}'"); long startTime = DateTime.Now.Millisecond; byte[] buf = File.ReadAllBytes(filename); BlzResult result = BlzCoder.BLZ_Decode(buf); if (result != null) { BlzCoder.Save(filename, result.buffer, result.length); } Console.Write(" - done, time=" + (DateTime.Now.Millisecond - startTime) + "ms"); Console.Write(Environment.NewLine + ""); } catch (IOException e) { Console.Write(Environment.NewLine + "File read error" + Environment.NewLine + e); } }
private void BLZ_Encode(string filename, int mode) { try { Console.Write("Now encoding {0}", filename); var stopwatch = new Stopwatch(); stopwatch.Start(); byte[] buf = File.ReadAllBytes(filename); BlzResult result = this.BLZ_Encode(buf, mode); if (result != null) { BlzCoder.Save(filename, result.buffer, result.length); } stopwatch.Stop(); Console.Write(Environment.NewLine + "Done, time elapsed = " + stopwatch.ElapsedMilliseconds + "ms" + Environment.NewLine); } catch (IOException e) { Console.Write(Environment.NewLine + "File read error" + Environment.NewLine + e + Environment.NewLine); } }
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)); }