IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Delphi Discussion :

Compression zlib: string > pointer > string


Sujet :

Delphi

  1. #1
    Membre régulier
    Profil pro
    Directeur
    Inscrit en
    Juin 2005
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Directeur

    Informations forums :
    Inscription : Juin 2005
    Messages : 113
    Points : 87
    Points
    87
    Par défaut Compression zlib: string > pointer > string
    Salut à tous, j'ai un petit probleme, voici comment ca se présente:
    Un ami m'a donné un code exemplatif pour la compression zlib, il utilise les streams:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    unit Unit1;
     
    interface
     
    uses
      Windows, Messages, SysUtils, Variants, zlib, Classes, Graphics, Controls, Forms,
      Dialogs, StdCtrls;
     
    type
      TForm1 = class(TForm)
        Button1: TButton;
        Button2: TButton;
        procedure Button1Click(Sender: TObject);
        procedure Button2Click(Sender: TObject);
      private
        { Déclarations privées }
      public
        { Déclarations publiques }
      end;
     
    var
      Form1: TForm1;
     
    implementation
     
    {$R *.dfm}
     
    procedure Decompresser(path : String);
    var
     InpBuf, OutBuf: Pointer;
     OutBytes, sz: Integer;
     outStream,inpStream: TMemoryStream;
    begin
     InpBuf := nil;
     OutBuf := nil;
     InpStream := TMemoryStream.Create;
     InpStream.LoadFromFile(path);
     inpstream.Read(sz,sizeof(integer));
     outStream := TMemoryStream.Create;
     if sz > 0 then
      try
       GetMem(InpBuf, sz);
       inpStream.Read(InpBuf^, sz);
       DecompressBuf(InpBuf, sz, 0, OutBuf, OutBytes);
       outStream.Write(OutBuf^, OutBytes);
       OutStream.Seek(SoFromBeginning,0);
       InpStream.Size := 0;
       inpStream.CopyFrom(OutStream,OutStream.Size);
       InpStream.Seek(SoFromBeginning,0);
       OutStream.SaveToFile(path);
      finally
       if InpBuf <> nil then FreeMem(InpBuf);
       if OutBuf <> nil then FreeMem(OutBuf);
       OutStream.Free;
      end;
    end;
     
     
    Procedure Compresser(path : String);
    var
     InpBuf, OutBuf: Pointer;
     InpBytes, OutBytes: Integer;
     outStream,inpStream: TMemoryStream;
    begin
     InpBuf := nil;
     OutBuf := nil;
     InpStream := TMemoryStream.Create;
     InpStream.LoadFromFile(path);
     outStream := TMemoryStream.Create;
     try
      GetMem(InpBuf, inpStream.Size);
      inpStream.Position := 0;
      InpBytes := inpStream.Read(InpBuf^, inpStream.Size);
      CompressBuf(InpBuf, InpBytes, OutBuf, OutBytes);
      outstream.Write(Outbytes,sizeof(integer));
      outStream.Write(OutBuf^, OutBytes);
      OutStream.Seek(SoFromBeginning,0);
      InpStream.Size := 0;
      inpStream.CopyFrom(OutStream,OutStream.Size);
      InpStream.Seek(SoFromBeginning,0);
      OutStream.SaveToFile(path);
     finally
      if InpBuf <> nil then FreeMem(InpBuf);
      if OutBuf <> nil then FreeMem(OutBuf);
      OutStream.Free;
     end;
    end;

    Pour ma part, j'ai un programme de cryptage d'executable, et j'aimerais y integrer cette fonction de compression pour rendre le exe plus petit. Le probleme c'est que j'utilise non pas des streams mais des strings:
    Déclaration des vars:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var
      resultat: boolean;
      InputName, OutputName, IString, OString, InSize, SizeOfImg, Tmp, SI, SO: string;
      RHandle, RSize, Input, Output, Bytes, eofsize, b: dword;
      i, x, y, BI, BO: integer;
      RPoint: pchar;
      RLoc: HRSRC;
      e, PI, PO: pointer;
      fOutput: TFileStream;
      SectionTable: TSectionTable;
    Morceau de code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [...]
              Input := CreateFile(pchar(InputName), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    [...]
              i := GetFileSize(InputName);
              Setlength(IString, i);
              ReadFile(Input, IString[1], i, Bytes, nil);
     
              BI := i;
              SI := IString;
              PI := pchar(SI);
              CompressBuf(PI, BI, PO, BO);
              Setlength(SO, BO);
              SO := pchar(PO);
    [...]
    Je pense que ceci est erroné, quand j'utilise le code de mon amis, calc.exe, une fois compressé, tourne dans les 50Ko. Ici, mon string SO contenant calc fait 3Ko ... probleme ... (pourtant, si je fais un ShowMessage(IntToStr(BO)); j'ai bien les 50Ko)
    Je pense que c'est mon utilisation des strings et pointeurs qui est en cause, je fais sans doute qqch de travers, mais quoi ? (le SO := pchar(PO); ???) Je ne suis pas encore très familiarisé avec les pointeurs donc si qq1 pouvait m'aiguiller...

    Merci d'avance

    PS:
    j'ai essayé:
    SO := pchar(PO^); >> Access violation
    SO := String(PO); >> Access violation

  2. #2
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Ton transtypage en PChar est tout ça fait correct, mais comme les PChar s'arrêtent au premier caractère nul, elles ne sont pas du tout adaptées à la gestion de chaînes binaires, ce que les string du Pascal font très bien.

    Peut-on avoir la déclaration et une explication sur CompressBuf, puisque c'est là que se pose le problème ?

  3. #3
    Membre régulier
    Profil pro
    Directeur
    Inscrit en
    Juin 2005
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Directeur

    Informations forums :
    Inscription : Juin 2005
    Messages : 113
    Points : 87
    Points
    87
    Par défaut
    Bah, compressbuf() est dans zlib et la déclaration est:
    procedure CompressBuf(const InBuf: Pointer; InBytes: Integer;
    out OutBuf: Pointer; out OutBytes: Integer);

    Mais, le compressbuf() à l'air de fonctionner vu que BO (BytesOut) vaut 50Ko.
    Donc le prob vient de mon pchar, pck oui, des nullbytes, il y en a bcp ...
    Il y a moyen de contourner le probleme ? Parcequ'il me semble qu'un string s'arrete aussi au premier nullbytes si je me trompe pas, pourtant ca ne m'a jamais poser probleme.

  4. #4
    Expert éminent sénior

    Avatar de sjrd
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juin 2004
    Messages
    4 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : Suisse

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2004
    Messages : 4 517
    Points : 10 154
    Points
    10 154
    Par défaut
    Il ne faut pas contourner le problème, il faut s'y prendre correctement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ...
    SI := IString;
    CompressBuf(Pointer(SI), Length(SI), PO, BO);
    SetLength(SO, BO);
    Move(PO^, Pointer(SO)^, BO);
    FreeMem(PO);
    Et c'est fait, sans passer par une seule PChar

  5. #5
    Membre régulier
    Profil pro
    Directeur
    Inscrit en
    Juin 2005
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Directeur

    Informations forums :
    Inscription : Juin 2005
    Messages : 113
    Points : 87
    Points
    87
    Par défaut
    Je vais tester ca, merci

    Ca fonctionne niquel, merci bcp

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Compresser un dossier avec Compress::Zlib
    Par mobscene dans le forum Modules
    Réponses: 1
    Dernier message: 17/11/2006, 21h13
  2. [Couper un String]par un autre String
    Par Terminator dans le forum Langage
    Réponses: 5
    Dernier message: 28/04/2006, 07h45
  3. [string] vérifier si une string en contient une autre
    Par vasilov dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 16/12/2005, 14h50
  4. [Info]Créer un tableau de String à partir d'autres String
    Par Nasky dans le forum Collection et Stream
    Réponses: 21
    Dernier message: 06/07/2005, 11h46
  5. [STRING]Contenu d'un String <> vers &lt; et &g
    Par TreizeSegments dans le forum Entrée/Sortie
    Réponses: 4
    Dernier message: 03/08/2004, 08h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo