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

Lazarus Pascal Discussion :

[3.4] Question sur la récupération des infos du header dans des fichiers .bmp [Lazarus]


Sujet :

Lazarus Pascal

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 132
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 132
    Par défaut [3.4] Question sur la récupération des infos du header dans des fichiers .bmp
    Bonjour,

    ça faisait longtemps que je ne m'étais pas pris la tête grave avec des bitmaps, alors voilà, celle-ci n'est pas triste :
    j'ai en haut un fichier 24bits identifié comme tel par un éditeur hexa, fichier constitué de 6 pixels et c'est tout, soit 78 octets.
    En bas le même à qui j'ai rajouté le canal Alpha grâce à The Gimp, du coup il monte à 94 octets, différence 16 octets.

    Le problème c'est le retour des infos pour comparaison : aucune différence !
    Nom : 78-94ko.png
Affichages : 253
Taille : 41,5 Ko

    Comment cela est-il possible ?
    une fiche, deux boutons, un mémo et qq lignes 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
    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
    function its(i:integer):string; begin result:=IntToStr(i); end;
     
    procedure DumpMem(Data: pCardinal; Size: integer);
    var
      i: Integer;
      px: tRGBAQuad;
    begin
      for i := 0 to Size - 1 do begin
        px := tRGBAQuad(Data[i]);
        with px do
          Form1.memo1.Lines.Add(Format('%s %.3u, %s %.3u, %s %.3u, %s %.3u', 
            ['Red', Red, 'Green', Green, 'Blue', Blue, 'Alpha', Alpha]));
      end;
    end;
     
    procedure TForm1.Button1Click(Sender: TObject);
    var
       ImgReader: TLazReaderBMP;
       IntfImg: TLazIntfImage;     // IntfGraphics
       rid: TRawImageDescription;  // GraphType 
    begin
       ImgReader := TLazReaderBMP.Create;
       IntfImg   := TLazIntfImage.Create(0,0);
     
       rid.Init_BPP32_B8G8R8A8_BIO_TTB(0, 0); // there is
       IntfImg.DataDescription := rid;        // solution
     
       IntfImg.LoadFromFile(Application.Location + 'MS_3x2_2818.bmp', ImgReader);
    //   IntfImg.LoadFromFile(Application.Location + 'MS_3x2_3820.bmp', ImgReader);
     
       memo1.Lines.Add('MS_3x2_2818.bmp :');
       memo1.Lines.Add('IntfImg.PixelData = '+its(SizeOf(IntfImg.PixelData))+ ', DDH : ' + its(rid.Height) + ', DDW : ' + its(rid.Width));
       memo1.Lines.Add('BitsPerPixel : ' + its(rid.BitsPerPixel) + ', Depth : ' + its(rid.Depth));
    ////   DumpMem(pCardinal(IntfImg.PixelData), IntfImg.DataDescription.Height * IntfImg.DataDescription.Width);
       memo1.Lines.Add('');
    // curieux : BitsPerPixel : 32, Depth : 32, examen hexa --> 28 @ 0E, 18 @ 1C !...
    // j'aurais dû avoir l'une (au moins) des deux variables = 24 (18hex=24dec, 20=32)
     
       ImgReader.Destroy;
       IntfImg.Destroy;
    end;
     
    procedure TForm1.Button2Click(Sender: TObject);
    var
       ImgReader: TLazReaderBMP;
       IntfImg: TLazIntfImage;     // IntfGraphics
       rid: TRawImageDescription;  // GraphType 
    begin
       ImgReader := TLazReaderBMP.Create;
       IntfImg   := TLazIntfImage.Create(0,0);
     
       rid.Init_BPP32_B8G8R8A8_BIO_TTB(0, 0); // there is
       IntfImg.DataDescription := rid;        // solution
     
      // IntfImg.LoadFromFile(Application.Location + 'MS_3x2_2818.bmp', ImgReader);
       IntfImg.LoadFromFile(Application.Location + 'MS_3x2_3820.bmp', ImgReader);
     
       memo1.Lines.Add('MS_3x2_3820.bmp :');
       memo1.Lines.Add('IntfImg.PixelData = '+its(SizeOf(IntfImg.PixelData))+ ', DDH : ' + its(rid.Height) + ', DDW : ' + its(rid.Width));
       memo1.Lines.Add('BitsPerPixel : ' + its(rid.BitsPerPixel) + ', Depth : ' + its(rid.Depth));
    ////   DumpMem(pCardinal(IntfImg.PixelData), IntfImg.DataDescription.Height * IntfImg.DataDescription.Width);
       memo1.Lines.Add('');
     
       ImgReader.Destroy;
       IntfImg.Destroy;
    end;
    Et les fichiers : 2fichiers_bmp.zip
    (obligé de les zipper ensemble, le forum m'a dit "fichier non valide" pour le premier... )

    Merci pour vos lumières.

  2. #2
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 638
    Par défaut
    Bonjour,

    Je n'ai pas la lumière à tous les étages , aussi je me suis contenté d'utiliser Hexplorer (un éditeur hexa qui a le bon goût de déchiffrer les en-têtes des BMP).

    Le MS_3x2_3820.bmp a un BMI_size de 56 contre 40 pour le MS_3x2_2820.bmp soit 16 octets donc 4 uint32 de plus. Ou en corolaire l'adresse du début d'image pixel_offset qui passe de 70 à 54.

    Mais l'explication ne s'arrête pas là.

    En effet, comme le 28 est codé sur 3 octets par couleur contre 4 pour le 38 on devrait avoir une différence entre les deux images augmentée de 6 octets puisqu'il y a 6 couleurs. Ce qui n'est pas.

    Je pense qu'il y a un alignement des lignes à un multiple de 4 octets soit 32 bits d'où un bourrage des lignes avec 3 octets à 0 (9 octets pour les couleurs + 3 et nous avons le multiple de 4 attendu).

    J'ai résumé rapidement cela dans un PDF : BMPP 3x2.pdf

    Ceci étant, le format que le programme affiche est celui en mémoire et non celui du fichier stocké. On pourrait légitimement penser qu'ils devraient s'aligner l'un sur l'autre mais la contrainte d'alignement mémoire sur des multiples de 4 est beaucoup forte qu'en stockage. Sans alignement, il faudrait 6 accès mémoire pour 4 pixels consécutifs soit un temps d'accès augmenté de 50 %. Il n'est donc pas trop surprenant que le Raw travaille avec des 32 bits même si l'un des octets n'est pas utile. C'est un choix assez classique en informatique : du temps contre de l'espace.

    Salutations

  3. #3
    Expert confirmé
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 132
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 132
    Par défaut
    Bonjour,

    Curieux que tu parles de 2820 (qui existe chez moi) alors que le .zip ne contient que 3820 et 2818...
    En fait, en examinant attentivement le dernier paragraphe de ton (très joli) fichier.pdf, je constate que ce que tu appelles 2820 est en fait pour moi un 2818 !

    38 vs 28 (en hex, en dec c'est 40 vs 56) c'est à l'adresse 0E, c'est le BMI_size, et
    18 vs 20 (en hex, en dec c'est 24 vs 32) c'est à l'adresse 1C et c'est le Bits_per_pixel.

    Et donc je me base sur ces infos pour nommer mes fichiers, sinon c'est l'enfer.

    Mais c'est la première fois de my life que je lis ça :
    Citation Envoyé par Guesset Voir le message
    Ceci étant, le format que le programme affiche est celui en mémoire et non celui du fichier stocké.
    Ça ne m'était jamais venu à l'esprit, et effectivement, ça change tout !



    Citation Envoyé par Guesset Voir le message
    Bourrage d’alignement 32 bits ?
    Absolument, si on considère le fichier 2820 comme un 2818 (tel que c'est écrit dans le pdf juste au-dessus de la couleur 7FBFBF).

    Mais la fin de la page 1 est plus complexe :
    Citation Envoyé par Guesset Voir le message
    Bmi_size qui passe de 56 octets à 40 octets ?
    J'aurais plutôt dit Bmi_size qui passe de 40 octets à 56 octets ?
    car on est à la version 3 du header, là. https://en.wikipedia.org/wiki/BMP_file_format

    À l'adresse 22 se trouve "Size of the bitmap data in bytes. This number must be rounded to the next 4 byte boundary." où l'on peut lire, pour les deux fichiers, 18hex soit 24dec.
    On a ensuite 4 dword (Hres, Vres, Colors, Important Colors)
    Et enfin les données pour le 2818 :
    pour chaque ligne, on a 3 pixels de 3 bytes + un padding de 3 bytes pour que la ligne soit divisible par 4.

    Pour le 3820, il y a d'abord et en plus si v3 du header 4 dwords : biRedMask, biGreenMask, biBlueMask, bitAlphaMask puis pour chaque ligne, les 3 pixels de 4 bytes et pas de padding.

    Pour bien préciser mon discours, j'ai retrouvé ça dans mes archives :
    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
    TBitmapInfoHeaderV3 = packed record   // size 56   inconnu chez MSDN    identique à v2 sauf biAlphaMask en plus
      biSize: dWord;   {size of tbitmapinfoheader (40_10)} // 4   14   0E 28_16 soit 40_10
      biWidth: Longint;  {bitmap width -- doit être paire} // 4   18   12
      biHeight: Longint; {height of bitmap}                // 4   22   16
      biPlanes: Word;    {always 1}                        // 2   26   1A, dessous = 2  28  1C
      biBitCount: Word;  {Bits par pixel (1=monochrome, 4=16 couls, 8=256 couls, 24=16 M de couls, 32=16 M aussi)}
      biCompression: dWord;   {compression used}           // 4   30   1E
        //0 or BI_RGB: none, 1 or BI_RLE8: RLE 8-bits per pixel,2 or BI_ RLE4: 4-bit per pixel,3 or BI_BITFIELDS: Bitfields
      biSizeImage: dWord;     {size of the pixel data}     // 4   34   22  (utile uniquement si compacté)
      biXPelsPerMeter: Longint; {not used, 0}              // 4   38   26
      biYPelsPerMeter: Longint; {not used, 0}              // 4   42   2A
      biClrUsed: dWord;     {nbr of colors used, set to 0} // 4   46   2E
      biClrImportant: dWord;  {important colors, set to 0} // 4   50   32
      biRedMask: dWord;
      biGreenMask: dWord;
      biBlueMask: dWord;
      bitAlphaMask: dWord;
    end;
    Et on peut aussi apprendre par cœur le contenu de ce lien,
    https://en.wikipedia.org/wiki/BMP_file_format

    Bon week-end,

  4. #4
    Membre Expert

    Homme Profil pro
    Directeur de projet
    Inscrit en
    Mai 2013
    Messages
    1 638
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Directeur de projet
    Secteur : Service public

    Informations forums :
    Inscription : Mai 2013
    Messages : 1 638
    Par défaut
    Bonjour,

    Copier coller sauvage des noms de fichiers. Heureusement (?) ma paresse gomme cette erreur en abrégeant le tout en 38 et 28.

    Je pars toujours du 38 (le plus gros) qui se trouve alimenter les premières colonnes du tableau de comparaison. Mais rien n'empêche de partir du 28 (le plus petit)

    J'ai tendance à conserver une seule logique : rigueur ou rigidité ?

    Salutations

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

Discussions similaires

  1. [Toutes versions] Question sur la sécurité des fichiers xlsm envoyés par mail
    Par Philippe Tulliez dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 22/06/2023, 15h43
  2. Question sur le fonctionnement des "fichiers ouverts"
    Par Lung dans le forum API, COM et SDKs
    Réponses: 9
    Dernier message: 17/03/2012, 15h28
  3. Question sur le fonctionnement des "fichiers ouverts"
    Par Lung dans le forum Windows Serveur
    Réponses: 0
    Dernier message: 08/03/2012, 08h33
  4. Question sur le nom des fichiers
    Par bilal_sayed1 dans le forum Débuter
    Réponses: 9
    Dernier message: 16/02/2010, 17h50

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