Hallo, wertes Forum.
Ich habe ein Problem mit einer Methode, die die zlib-komprimierten Bytes der Table, bzw. einer Datei in einem Archiv dekomprimiert und als Array zurück gibt.
Hier besagte Methode:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23:
| public static byte[] DecompressBytes(byte[] CompressedBytes, int BufferLenght) { byte[] Buffer = new byte[BufferLenght]; byte[] DecompressedData; using (MemoryStream ms = new MemoryStream()) { using (MemoryStream ms2 = new MemoryStream(CompressedBytes)) { ms2.ReadByte(); ms2.ReadByte(); using (DeflateStream ds = new DeflateStream(ms2, CompressionMode.Decompress)) { int Count; while ((Count = ds.Read(Buffer, 0, BufferLenght)) > 0) { ms.Write(Buffer, 0, Count); } } } DecompressedData = ms.ToArray(); } return DecompressedData; } |
So, nun fang ich an, meine Datei einzulesen und zu bestimmen, ob sie auch wirklich das richtige Dateiformat aufweist und dieses die richtige Version hat und lesen die Table aus:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
| Archive.MoM = br.ReadBytes(15); Archive.WaterMark = br.ReadBytes(15); Archive.TableOffset = br.ReadUInt32(); Archive.Seeds = br.ReadUInt32(); Archive.FileCount = br.ReadUInt32(); Archive.Version = br.ReadUInt32(); br.BaseStream.Position += Archive.TableOffset; Archive.TrueFileCount = Archive.FileCount - Archive.Seeds - 7; Archive.TableSizeCompressed = br.ReadUInt32(); Archive.TableSizeDecompressed = br.ReadUInt32(); Archive.TableCompressed = new byte[Archive.TableSizeCompressed]; br.Read(Archive.TableCompressed, 0, (int)Archive.TableSizeCompressed); Archive.TableDecompressed = DecompressBytes(Archive.TableCompressed, 1024); |
In der letzten Zeile wird die Methode das erste Mal aufgerufen, um zu überprüfen ob die Table-Größe korrekt ist. An dieser Stelle ist
Archive.TableCompressed ein 798445 Felder großes Byte-Array und
DecompressBytes funktioniert prächtig.
Wenn ich nun aber anfange, die erste Datei auszulesen:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24:
| int Offset = 0; for (int i = 0; i < Archive.TrueFileCount; i++) { string FileName = ""; while ((char)Archive.TableDecompressed[Offset] != '\0') FileName += (char)Archive.TableDecompressed[Offset++]; Offset++; GrfContent CurrentFile = new GrfContent(); CurrentFile.NameString = FileName; CurrentFile.NameByte = Encoding.Default.GetBytes(FileName); CurrentFile.LenghtCompressed = BitConverter.ToUInt32(Archive.TableDecompressed, Offset); Offset += 4; CurrentFile.LenghtAligned = BitConverter.ToUInt32(Archive.TableDecompressed, Offset); Offset += 4; CurrentFile.LenghtDecompressed = BitConverter.ToUInt32(Archive.TableDecompressed, Offset); Offset += 4; CurrentFile.Flags = Archive.TableDecompressed[Offset++]; CurrentFile.Position = BitConverter.ToUInt32(Archive.TableDecompressed, Offset); br.BaseStream.Position = CurrentFile.Position + 46; CurrentFile.FileContentCompressed = new byte[CurrentFile.LenghtCompressed]; br.Read(CurrentFile.FileContentCompressed, 0, (int)CurrentFile.LenghtCompressed); CurrentFile.FileContentDecompressed = DecompressBytes(CurrentFile.FileContentCompressed, 1024); } |
Soweit sollte eigentlich alles geklappt haben, da
CurrentFile.NameString einen vernünftigen Wert beinhaltet und es wird mit
CurrentFile.FileContentCompressed ein 8729 Felder großes Byte-Array übergeben. Allerdings produziert
DecompressBytes nun einen Fehler.
An der Stelle
while ((Count = ds.Read(Buffer, 0, BufferLenght)) > 0) wird gemeldet, dass
die Blocklänge nicht dem Komplement entspricht. (
InvalidDataException)
Tja, damit kann ich leider nicht wirklich etwas anfangen und konnte auch mit Google keine hilfreichen Hinweise finden.
Falls es wichtig ist... Es wird versucht, die Bytes einer Bitmap-Datei zu dekomprimieren.
Hier noch eine bescheidene Information zum Dateiformat:
lunardew.com/topic/11
Eine bessere Erklärung konnte ich leider nirgendwo finden.
// EDIT:
Wenn ich es mit der zlib.dll und einer angepassten Mehtode probiere, funktioniert es leider auch nicht.
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| public byte[] DecompressBytes(byte[] bytes) { byte[] nbytes = new byte[1024]; byte[] decompressedData = new byte[0]; using (MemoryStream ms2 = new MemoryStream()) { using (MemoryStream ms = new MemoryStream(bytes)) { using (ZOutputStream ds = new ZOutputStream(ms2)) { int offset = 0; while ((offset = ms.Read(nbytes, 0, nbytes.Length)) > 0) { ds.Write(nbytes, 0, offset); } decompressedData = ms2.ToArray(); } } } return decompressedData; } |
Ich bekomme nun - wieder sobald die erste Datei (.bmp) bearbeitet werden soll - eine
ZStreamException (inflating: unknown compression method) an der Stelle
ds.Write(nbytes, 0, offset);... Es steht aber unumstößlich fest, dass die diese Datei zlib-komprimiert ist, daher bin ich echt ratlos.
Ich bin wie immer über jede Hilfe froh.
//EDIT 11.02.2010
Hat sich erledigt, hab das Dekomprimieren der einzelnen Dateien ausgelagert und nun geht, warum auch immer...
svn.cs-hro.de/eaIEC/eaIEC/Classes/GRF.cs
MfG