[C#] Suche LZX Lib (Thema umbenannt)

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

[C#] Suche LZX Lib (Thema umbenannt)

Beitrag von BeRsErKeR »

Ich hab mein ursprüngliches Vorhaben aufgegeben und suche nun nach einer LZX Compression Lib (siehe ab 4. Beitrag).

Hallo,

ich schlag mich grad mit dem compound file Kram von MS rum. Ich möchte CHM-Dateien öffnen, ändern und speichern können und nutze dafür die IStorage- und IStream-Klassen.

Die entscheidenen Funktionen habe ich wie folgt importiert:

Code: Alles auswählen

[return: MarshalAs(UnmanagedType.Interface)]
IStorage StgCreateDocfile([In, MarshalAs(UnmanagedType.BStr)] string pwcsName, int grfMode, int reserved);
[return: MarshalAs(UnmanagedType.Interface)]
IStorage StgCreateDocfile([In, MarshalAs(UnmanagedType.BStr)] string pwcsName, int grfMode, int reserved);
Soweit funktioniert das alles. Mein Problem ist nun, dass diese Funktionen (bzw. das COM-Objekt) Dateien anlegen bzw. öffnen. Ich möchte aber nachdem ich das IStorage freigebe wieder Zugriff auf die Datei haben (Neu laden, Kopieren, usw). Leider ist die Datei blockiert, bis das ganze Programm beendet wird. Ich habe es mit folgenden Aufrufen probiert:

Code: Alles auswählen

IntPtr storage_ptr = Marshal.GetIUnknownForObject(_storage);
int refCount;
do
{
    refCount = Marshal.Release(storage_ptr);
} while (refCount > 0);
                
_storage = null;

Code: Alles auswählen

Marshal.FinalReleaseComObject(_storage);
_storage = null;
Beides zeigt keinen Erfolg. Selbst das Flag STGM_DELETEONRELEASE (was zwar nicht gewollt ist aber beim Release wenigstens die Datei löschen sollte) funktioniert nicht. Auch ein Commit-Aufruf vor dem Release brachte keinen Erfolg.

Ich weiß nicht ganz ob das COM-Objekt dennoch weiterlebt oder einfach die Datei vom COM-Objekt nicht freigegeben wird.

Kann mir da wer helfen?

Bei Google fand ich nur die Freigabe über die obige do-while-Schleife. Dort ging es wohl; bei mir leider nicht.
Zuletzt geändert von BeRsErKeR am 11.07.2012, 15:36, insgesamt 4-mal geändert.
Ohne Input kein Output.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C#] StgOpenStorage / StgCreateDocfile -> file handle

Beitrag von BeRsErKeR »

Nachtrag: Ich weiß, dass die beiden Funktionen veraltet sind und tatsächlich konnte ich mit StgCreateStorageEx anstelle von StgCreateDocfile die Dateien im Anschluß wieder verwenden. Leider erzeugt diese Funktion immer ungültige CHM-Dateien, die ich nicht lesen kann. Und StgOpenStorageEx kann auch keine meiner validen CHM-Dateien lesen.

Aber es muss doch irgendwie möglich sein, dem COM-Objekt zu sagen, dass er die Datei wieder freigibt. Schon schlimm genug, dass man kein CloseFile oder ähnliches hat ...

Ich hatte auch schon STGM_TRANSACTED probiert um das Ganze zu umgehen. Allerdings wird das irgendwie von meinem Rechner nicht unterstützt (auf genau dem Rechner MUSS es ohne Änderungen laufen!). Ich erhalte STG_E_UNIMPLEMENTEDFUNCTION sobald ich STGM_TRANSACTED setze. Wohlgemerkt bei StgOpenStorage, für die dieser Fehler nicht spezifiziert ist...

Komisch ist auch, dass StgOpenStorageEx z.B. den Fehler STG_E_FILEALREADEXISTS liefert, was beim Öffnen nicht passieren / stören sollte. Viel mehr noch ist es eigentlich eine Grundvoraussetzung, dass eine Datei vorhanden ist, wenn sie geöffnet werden soll. Die bei MS sind schon Spaßvögel... Der Fehler ist natürlich auch nicht für diese Funktion spezifiziert.

ich hasse diese Scheiße ... muss sie aber leider verwenden ...
Ohne Input kein Output.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C#] StgOpenStorage / StgCreateDocfile -> file handle

Beitrag von BeRsErKeR »

Hmm hat denn keiner mal das COM-Objekt fürs compound file format verwendet? Excel- und Word-Dateien kann man ja schon ab und an mal öffnen und speichern wollen.
Ohne Input kein Output.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C#] StgOpenStorage / StgCreateDocfile -> file handle

Beitrag von BeRsErKeR »

Ok ich hab es nun aufgegeben und implementiere das Lesen und Schreiben von CHM-Dateien selbst. Allerdings stoße ich hier auf die Komprimierung per (MS) LZX. Kennt dafür jemand eine gute Lib? Am liebsten direkt C#-Code, von mir aus aber auch ne DLL, die ich per DllImport nutzen kann. Wichtig ist dabei, dass man Daten komprimieren und dekomprimieren kann und bestimmte Parameter wie WindowSize vorgeben kann. Wichtig ist auch, dass man das auf rohe Daten und nicht nur auf Dateien anwenden kann.

Wenn ich nun wirklich noch Huffman + LZX selbst implementieren soll krieg ich nen Schlaganfall. Ich suche schon seit Tagen nach ner brauchbaren Lib, bislang leider erfolglos. Ich kann nicht verstehen, dass das noch niemand gemacht hat. Meist gibts nur komplette Tools, die gleich alles machen. Ich brauch aber nur ein kleines Stück als Lib oder Code.
Ohne Input kein Output.
Benutzeravatar
BeRsErKeR
Establishment
Beiträge: 689
Registriert: 27.04.2002, 22:01

Re: [C#] Suche LZX Lib (Thema umbenannt)

Beitrag von BeRsErKeR »

Edit: Ok ich glaube ich komme so langsam dahinter. :)


Ich krieg diesen Scheiß LZX Kram einfach nicht hin. Vielleicht könnt ihr mir ja helfen, wenn ich euch was zum Probieren gebe.

LZX-Spezifikation:

http://msdn.microsoft.com/en-us/library ... sionformat
Genauer: http://msdn.microsoft.com/en-us/library ... x#lzx_form

Anfangsdaten in Hex-Form:

Code: Alles auswählen

1010030000004363702200006F7635E9
CF933FFB4E53DDEEFA6E81A8AEB11195
BC014120BA436DF9FD8445F115B9B8AA
B4DBFFDE4FDF343D0030320546230080
07084BC94B7E386D25091961747DA42F
F799F4A46CC914B31CF04BA1059125EC
287BBB533B6C72EE760F3FCA02DB76BF
6FCA0ABB9C6FFC80016C5CCEE53C9C47
7EE5C01FE0E8A0B78D078116F0D3151D
743CEF4B8F79A4A7DF9284F000004600
8C660000DFA0FFFEDFF7F77D7677DBEE
B7B66E4B56B06A4BB6B14A56C9467637
DBEEB65DF69F6DD6D63615D8486A2288
208035081F04B138247C44119027237C
10E81F048050CDFA968C8A482C5C0285
ACC569713299D1FAA98AF12B0C66E550
B14BA94C0045D36531A823D131972D2D
342FAC61800DA96D0643AD542C4A920D
CBB53463C8814A35023243BA4C6698C6
92467D90169BA84B9529D86B53F477AE
C85294280539B15A49BF08E2490F5AE6
0C0509837468614E822A0461E4D93393
926EB3996E5494948AC9FA878B65E504
B42C5EA3A21142E6736AC65C92903253
677F99A9FB920F0809A44596537D5759
61C2898E5E0272C121FBA8955D63A379
86CEC08B178A9F302E51E4AD46DD353C
F38C9C539147A563DA3CCCE5CFB9F3B6
D3D448CE57D45DE8022DF2FA58C5E882
A755A864105073D4D174CBF530171009
716CC1CD7226540A51BD6E48739FA915
50D7DFD84A629AC71138194836A25574
82FE41BE2B821D2B6FAADD178D515E79
9CB8CC97D06547E37D5A9B7DEB43B9ED
7ED08C5928C88D2E0733ADD10589B3D1
2CB13BF3F76A160298675B33D93E2D9F
926BFFAC6A265B54755AC47A680ABD4B
E59C8583D339EFB19B558A37703664C7
BA2854A6BA02463994195904E5F1140B
60B89DDB67989540ADE47200C03DD482

Mir würde schon reichen halbwegs realitätsnahe Huffman-Trees aus diesen Daten zu generieren. Es kommt einfach nur Grütze bei raus. Das stimmt vorn und hinten nicht. Solangsam glaub ich dass es da noch Daten gibt, die nicht in der Spec stehen oder die Reihenfolge doch anders ist. Ich hab schon ein paar Libs gesichtet, die alle so arbeiten wie mein Code (vom draufgucken her, testen ging nicht, weil die nicht für CHMs sondern anderen Kram ausgelegt sind), aber weder mein Code bringt was vernünftiges hervor, noch kann ich aus den Daten selbst etwas konstruieren, was halbwegs passen könnte.

Blocktypen gibt es nur mit der ID 1, 2 oder 3. Unter Annahme, dass der Blocktyp in den Bits 1-3 kodiert ist, wäre das immer 1 (auch wenn man die Bytes umdreht, wie gefordert), da beide Bytes 0x10 (16) sind. Also ein Verbatim-Block. Dann müssten MainPreTree, MainTree, RemainingMainPreTree, RemainingMainTree, LengthPreeTree und LengthTree folgen. Dazwischen noch 24 Bit für die unkomprimierte Länge (wobei das scheinbar nur einige Libs beachten!). Ich kann mir nicht vorstellen dass all die Libs nicht funktionieren, aber ich krieg es einfach nicht gebacken ...

Mir würde schon ein vernünftiger MainTree reichen...
Ohne Input kein Output.
Antworten