Komprimier Algo

Hier könnt Ihr gute, von Euch geschriebene Codes posten. Sie müssen auf jeden Fall funktionieren und sollten möglichst effizient, elegant und beispielhaft oder einfach nur cool sein.
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Komprimier Algo

Beitrag von MVXA »

Hallo !
Ich hab n Programm geschrieben, mit dem man 40 KB auf 8,06 KB runter schrauben kann. Der Trick ist: zuerst wird die Exe mit dem Algo in eine BMP umgewandelt. Danach wird die erstellte BMP mit dem RAR Algo in ein archiv umgewandelt. Wenn man die Exe ohne den Algo verpacken würde, wäre das archiv ca. 0,40 KB größer. Ist zwar so gesehn nicht sonderlich viel, aber wenn man das vergleichsweise mit einer EXE machen würde, wäre der unterschied auch größer. Hier einfach mal der Code:

Code: Alles auswählen

Declare   Open_frmMain()
Declare.b Bin2BMP(strDatei.s, strDest.s)
Declare.b BMP2bin(strDatei.s, strDest.s)

Enumeration
    #frmMain
EndEnumeration

Enumeration
    #PrbProgress
    #imgData
EndEnumeration

Global Datei.s
Global FileGroesse.l
Global EventID.l

Datei = ProgramParameter()

Select GetExtensionPart(Datei)
    Case "bmp"
        If BMP2bin(Datei, SaveFileRequester("BMP Converter...", "", "*.* (Alle Dateien)|*.*", 0)) = #True
            MessageRequester("Fertig !", "Convertierung erfolgreich abgeschlossen !")        
        Else
            MessageRequester("Fehler !", "Fehler beim Öffnen der Datei !")
        EndIf           
    Case "exe"
        If Bin2BMP(Datei, SaveFileRequester("BMP Converter...", "", "*.* (Alle Dateien)|*.*", 0)) = #True
            MessageRequester("Fertig !", "Convertierung erfolgreich abgeschlossen !")
        Else
            MessageRequester("Fehler !", "Fehler beim Öffnen der Datei !")
        EndIf        
    Default
        Datei = OpenFileRequester("BMP Converter...", "", "*.* (Alle Dateien)|*.*", 0)
        If Bin2BMP(Datei, SaveFileRequester("BMP Converter...", "", "*.* (Alle Dateien)|*.*", 0)) = #True
            MessageRequester("Fertig !", "Convertierung erfolgreich abgeschlossen !")        
        Else
            MessageRequester("Fehler !", "Fehler beim Öffnen der Datei !")
        EndIf        
EndSelect

End

Procedure.b BMP2bin(strDatei.s, strDest.s)
    DefType.l FileHandle, ImageHandle, Proced, MyX, MyY, PointColor
    
    FileHandle  = OpenFile(#PB_Any, strDest)
    If FileHandle <> 0
        ImageHandle = LoadImage(#PB_Any, strDatei)
        If ImageHandle <> 0
            If StartDrawing(ImageOutput())
                Open_frmMain()
                
                Repeat
                    EventID = WindowEvent()
                    If EventID <> 0 
                        Select EventID
                            Case #PB_Event_CloseWindow
                                End
                        EndSelect
                    EndIf                    
                    
                    PointColor = Point(MyX, MyY)
                    If PointColor = RGB(255, 0, 0)
                        Break
                    Else
                        WriteByte(Red(PointColor))
                        Proced = Proced + 1 
                        If MyX = ImageWidth()
                            MyX = 0 
                            MyY = MyY + 1
                        Else
                            MyX = MyX + 1
                        EndIf
                        SetGadgetState(#PrbProgress, Val(StrF((MyX / 512) * 100,0)))
                    EndIf
                    
                ForEver
                
                ProcedureReturn #True
            Else 
                ProcedureReturn #False
            EndIf
        Else
            ProcedureReturn #False
        EndIf
    Else
        ProcedureReturn #False
    EndIf
EndProcedure

Procedure.b Bin2BMP(strDatei.s, strDest.s)
    DefType.l FileHandle, ImageHandle, Proced, MyX, MyY, Zeichen
    
    FileHandle = ReadFile(#PB_Any, strDatei)
    Debug Str(FileHandle) + "/" + strDatei
    If FileHandle <> 0 
        FileGroesse = FileSize(strDatei) 
        Open_frmMain()
        
        ImageHandle = CreateImage(#PB_Any, 512, (FileGroesse / 512) + 2)
        StartDrawing(ImageOutput())
        Box(0,0,512,ImageHeight(), RGB(255,255,255))
        StopDrawing()
        
        If StartDrawing(ImageOutput())
            While Eof(FileHandle) = 0
                EventID = WindowEvent()
                
                If EventID <> 0 
                    Select EventID
                        Case #PB_Event_CloseWindow
                            End
                    EndSelect
                EndIf
                
                Zeichen = ReadByte() & $FF
                Debug Str(Zeichen)
                Plot(MyX, MyY, RGB(Zeichen, Zeichen, Zeichen))
                Proced = Proced + 1 
                If MyX = 512
                    MyX = 0 
                    MyY = MyY + 1
                Else
                    MyX = MyX + 1
                EndIf
                
                RandomSeed(Date())
                SetGadgetState(#PrbProgress, Val(StrF((Proced / FileGroesse) * 100,0)))
                SetWindowTitle(#frmMain, StrF((Proced / FileGroesse) * 100, 2) + "%...")
            Wend
            Plot(MyX, MyY, RGB(255, 0, 0))
            StopDrawing()            
        EndIf
        
        If strDest <> ""
            SaveImage(ImageHandle, strDest)
            ProcedureReturn #True
        EndIf
    Else
        ProcedureReturn #False
    EndIf    
EndProcedure

Procedure Open_frmMain()
    If OpenWindow(#frmMain, 237, 272, 281, 41,  #PB_Window_SystemMenu | #PB_Window_TitleBar | #PB_Window_ScreenCentered , "BMP Convert")
        If CreateGadgetList(WindowID())
            ProgressBarGadget(#PrbProgress, 10, 10, 260, 20, 0, 100, #PB_ProgressBar_Smooth)
        EndIf
    EndIf
EndProcedure
Leider funzen Binärdateien leider noch nicht (sprich Exe). Wenn jemand abhilfe schaffen kann, danke !

edt.
Habe jetzt etwas verändert. Delay() raus gemacht und nun funktioniert das BIN2BMP. Aber BMP2BIN arbeitet noch nicht richtig. zumindest wird das umgewandelte Programm mit einem Error Dialog beendet.
Zuletzt geändert von MVXA am 28.10.2004 22:06, insgesamt 1-mal geändert.
Bild
Kristel
Beiträge: 72
Registriert: 30.08.2004 00:17

Re: Komprimier Algo

Beitrag von Kristel »

LittleFurz hat geschrieben:Der Trick ist: zuerst wird die Exe mit dem Algo in eine BMP umgewandelt.
LittleFurz hat geschrieben: Leider funzen Binärdateien leider noch nicht (sprich Exe). Wenn jemand abhilfe schaffen kann, danke !
:? :? :? Ist das nicht ein Wiederspruch ? :? :? :?
Benutzeravatar
Ynnus
Beiträge: 855
Registriert: 29.08.2004 01:37
Kontaktdaten:

Beitrag von Ynnus »

Öhm, Exe, Bmp, Rar, klingt etwas wirr. Ob man nun 400 byte spart oder nicht macht bei großen Daten wohl keinen Unterschied oder? Also da ist mir der Aufwand zu groß, da benutz ich lieber gleich WinRAR und fertig.

Und, ach du meine Güte, wie lange konventiert der denn für 270 KB große Dateien? 1 % nach 40 Sekunden, das ist doch wirklich zu langsam. Mit WinRAR bin ich da 1000 mal fertig. Ein wenig kommt es bei sowas auch auf Speed drauf an, und da liegt dein programm gerade noch etwas weit hinten...
EDIT: Wofür hast du da 2 mal ein Delay(1) drinne? Der komprimiert ohne gleich mehr als 10 mal so flott. (trotzdem noch recht langsam im Vergleich zu WinRAR und Co.)

EDIT2: Das spart 30 KB mehr als WinRAR bei einer Datei der Größe 280 KB. Naja... Dafür erstellt er erstmal 5 Minuten lang ein Bitmap welches 800 KB groß war, und dann darf man dieses manuell in ein RAR-Archiv wandeln. Also umständlicher gehts kaum. Dadurch muss ich ja mehrere Schritte machen, muss noch WinRAR drauf haben, und noch eine BMP löschen und und und. Also naja, das ist noch stark verbesserungsfähig.
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

also
1) ist das kein Programm /:-> sondern das sind 2 Funktionen und ein bischen Code um zu demonstrieren, wie die Funktionen arbeiten.
2)Ich habe in jeder Funktion nur EINMAL Delay(1) drin, damit mein schöner Prozessor nicht zu 100% ausgelastet wird. Wer es schnell will, der kann dann halt das Delay(1) löschen.

Ich schreibe später nochmal ein Programm, das eine Datei in einem Durchgang in eine BMP umwandelt und dann einem RAR Archiv hinzufügt.

Übrigens:
Das Programm kann sehr vorteilhaft sein. Mein Freund wollte mal auf seinen alten PC (der keine Netzwerkkarte hat) eine Datei kopieren und hat dazu eine Diskette benuzt. Dummerweise war das RAR Archiv aber genau 1 Byte zu groß. Da wäre das Tool echt nützlich gewesen.

@Kristel:
Nö, nicht wirklich ;) Unter VB geling mir dies auch mit einer EXE, nur unter PB funktioniert das nicht und ich sehe nicht wirklich warum :freak:
Bild
Benutzeravatar
freedimension
Admin
Beiträge: 1987
Registriert: 08.09.2004 13:19
Wohnort: Ludwigsburg
Kontaktdaten:

Beitrag von freedimension »

Hmm, du hast gar keine Vorsichtsmaßnahmen getroffen um deinen Code zu schützen. Sehr fahrlässig das ;-)

Finde es übrigens sehr interessant, dass man durch künstliches Aufblähen einer Datei diese beim Packen dann kleiner bekommt als das Original.
Wenn du jetzt noch erklären könntest warum das so ist ... :allright:
Beginne jeden Tag als ob es Absicht wäre!
Bild
BILDblog
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

mir ist das so ziehmlich egal ob es jemand in seinem programm verwendet oder nicht, wäre aber trozdem schön das er erwähnt von wem der code ursprünglich ist.

ich weiß selber nicht warum das so ist :freak:. Freund von mir erzählte mal, dass ne Firma n memorystick baut, der die Daten in Bildform schreibt und damit wesentlich mehr speicher zustande bekommt. Begeistert von der Idee hab ich den Algo mal selbst nachgebaut :freak:
Bild
Benubi
Beiträge: 186
Registriert: 22.10.2004 17:51
Wohnort: Berlin, Wedding

Beitrag von Benubi »

nun ich weiss ja auch nicht alles,

aber bei kompression werden daten vereinfacht; möglichweise farben neu definiert, oder zusammengelegt... (?)

du hast dann einen datenverlust, der für das AUGE nicht sichtbar ist; bei programmen kann man das allerdings nicht so einfach machen, da ein paar zeilen verlust das programm unbrauchbar machen...

stell dir vor du hast diese Befehlsnummern und die entsprechenden befehle:

1 If
2 else
3 end

das "bild" würde so oder ähnlich komprimiert werden:
1 und 2 sind OPTISCH kaum von einander zu unterscheiden... was nehmen wir ? ich bin für 2... also fängt deine abfrage mit einem falschen "assembler-befehl" an, nämlich mit 2 anstelle von 1. und dann fehlt vielleicht noch der folgende block...

für das auge ist es nicht sichtbar, aber es gibt dort einen datenverlust, und die programme werden so verändert und komprimiert, dass man das leider nicht rückgängig machen kann... wenn du eine 3 hast. woher willst du wissen, ob die 1 oder 2 vorher da war, oder ob es 3 und 0 oder 0 und 3 bedeutet ? siehste. und computer wissen noch weniger als wir :lol:


dennoch ein sehr interessanter ansatz, und ich möchte dich keinesfalls entmutigen. komprimierung ist eine wissenschaft für sich, und es werden tatsächlich immer neue methoden entwickelt....

komprimierung hat immer seine grenzen. i.d.r. ist es unmöglich, eine datei, bei der jedes aufeinander folgende byte verschieden ist, zu komprimieren, da du keine wiederholungen "vereinfachen kannst".

ich möchte aber nichts falsches sagen, am besten du schaust dich ein bissel im internet um...

das mit dem optischen speicher klingt interessant. allerdings könnte das alles mögliche sein...

1. CD-ROM (oder DVD etc...)
2. Ein Speicherkristall der mit 3 Laser ausgelesen wird (ich glaube sowas gibt es nur in der forschung oder bei star trek...)
3. etwas neues was ich nicht kenne...

viel Glück auf deiner Suche! vielleicht findest du ja doch noch was neues :wink:
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

es funktioniert ja, soger tadellos :freak: Allerdings halt nur in VB. Unter PB zickt das merkwürdiger weise. Ich kann mir auch nicht erklären warum. Wer will, kann auch den VB orginal hier posten. Die VB Version arbeitet auch wesentlich schneller, obwohl sie das gleich macht, wie die PB variante.

edt.
Bin schlauer ! PB scheint wohl ein paar bytes einfach verschwinen lassen :freak:. z.b. taucht die Farben ab hellgrau garnid auf :freak:. in der VB Variante sind ALLE farben mindestens einmal vorhanden
Bild
Benubi
Beiträge: 186
Registriert: 22.10.2004 17:51
Wohnort: Berlin, Wedding

Beitrag von Benubi »

LittleFurz hat geschrieben: Bin schlauer ! PB scheint wohl ein paar bytes einfach verschwinen lassen :freak:. z.b. taucht die Farben ab hellgrau garnid auf :freak:. in der VB Variante sind ALLE farben mindestens einmal vorhanden
ja, und windows komprimiert wahrscheinlich nicht die bilder, sondern nur winrar...

pb benutzt die ...Encoder() und Decoder() Libs... deshalb wird vielleicht das bild komprimiert und daten gehen verloren... BMP braucht auch 2 Bytes am Anfang für HöhexBreite (vor dem Bild) ... kannst du vielleicht ohne Kompression speichern [flag?], damit winrar das bild umso effektiver komprimieren kann ???
wäre ganz schön paradox... :?
Benutzeravatar
MVXA
Beiträge: 3823
Registriert: 11.09.2004 00:45
Wohnort: Bremen, Deutschland
Kontaktdaten:

Beitrag von MVXA »

hast du dir auch den code angesehn :freak: ? ich benutze KEINE DE und EN coder :freak: ich glaub, du begreifst nicht, was der Code genau macht.
Bild
Antworten