IRandomGenerator DetectEncryptionScheme() { var first_entry = Dir.First(); int signature = (File.View.ReadInt32(first_entry.Offset) >> 8) & 0xFFFF; byte seed = File.View.ReadByte(first_entry.Offset + first_entry.Size - 1); IRandomGenerator[] rng_list = { new LehmerRandomGenerator(), new CRuntimeRandomGenerator(), }; foreach (var rng in rng_list) { rng.SRand(seed); rng.Rand(); // skip LZSS control byte int test = signature; test ^= PakOpener.Key[rng.Rand() % PakOpener.Key.Length]; test ^= PakOpener.Key[rng.Rand() % PakOpener.Key.Length] << 8; // FIXME // as key is rather short, this detection could produce false results sometimes if (0x4D42 == test) // 'BM' { return(rng); } } throw new UnknownEncryptionScheme(); }
public byte[] ReadFrame(BdfFrame frame) { byte[] pixels; if (!frame.Incremental) { if (null != FirstFrame && 0 == frame.Number) { return(FirstFrame); } pixels = new byte[frame.Width * frame.Height * 3]; using (var input = File.CreateStream(frame.Offset, frame.Size)) DecodeFrame(input, pixels); if (null == FirstFrame && 0 == frame.Number) { FirstFrame = pixels; } } else { if (null == FirstFrame) { var base_frame = Dir.First() as BdfFrame; FirstFrame = new byte[base_frame.Width * base_frame.Height * 3]; using (var input = File.CreateStream(base_frame.Offset, base_frame.Size)) DecodeFrame(input, FirstFrame); } pixels = FirstFrame.Clone() as byte[]; int i = 1; foreach (BdfFrame entry in Dir.Skip(1)) { if (i++ > frame.Number) { break; } using (var input = File.CreateStream(entry.Offset, entry.Size)) DecodeFrame(input, pixels, entry.Incremental); } } return(pixels); }