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 :

Fichier BMP et encodage "BITFIELD" [Lazarus]


Sujet :

Lazarus Pascal

  1. #1
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut Fichier BMP et encodage "BITFIELD"
    Bonjour à tous

    Qui aurais pensé que lire un simple fichier BMP sois si compliqué ?

    Alors voila après la prise en charge du 24bits je suis passé au 32bits
    J'ai trouvé cette suite de test pour fichiers BMP : http://entropymine.com/jason/bmpsuite/
    pour tester et prendre en charge le maximum de cas possible.

    Au cas ou voici les liens sur lesquel j'essaye de m'appuyer

    Informations sur le format BMP :
    - https://fr.wikipedia.org/wiki/Windows_bitmap
    - https://en.wikipedia.org/wiki/BMP_file_format (plus complet que la version française)
    - http://www.alrj.org/docs/formats/bmp/BMP.htm
    - http://netghost.narod.ru/gff/graphic...ary/os2bmp.htm
    - http://www.drdobbs.com/the-bmp-file-...4409533?pgno=5

    Compression/Decompression :
    - http://netghost.narod.ru/gff/graphics/book/ch09_01.htm
    - https://fr.wikipedia.org/wiki/Codage_de_Huffman
    - http://tcharles.developpez.com/Huffman/


    Et là bien ; c'est du 50% de réussite et 50% d'échec. grosso modo.

    Voilà un capture d'écran des fichiers BMP 32Bits de test, vus dans l'explorateur de Windows.
    Entouré en jaune ce sont les fichiers que je charge et j'affiche correctement.

    Nom : apercu_fichier_test_bmp32_ex.jpg
Affichages : 879
Taille : 65,2 Ko


    Je n'arrive pas à comprendre comment Lazarus affiche correctement tous les fichiers.
    Les procédures et fonctions sur lesquelles je me suis basé sont celles présentes dans
    la classe TLazReadDIB de l'unité IntGraphics et dans l'unité fpBMPReader.


    1er cas
    avec les BMP encodés à 100% correctement
    - le fichier rgb32bfdef.bmp, c'est Ok

    Nom : rbg32bfdef-test1.jpg
Affichages : 1127
Taille : 102,1 Ko

    - le fichier rgb32bf.bmp, paf

    Nom : rbg32bf-test1.jpg
Affichages : 1299
Taille : 102,1 Ko

    Avez vous remarquez la valeur de "Depth" et d' "AlphaShift" pour le TBitmap ?
    Il le traite comme un 24bits !! et l'alphashift est à zero. Comparez avec "TGLZBitmap" à droite.

    Nb :
    - regardez la version du fichier BMP dans le memo à droite et en bas.
    - Les valeurs de RedMask, GreenMask, BlueMask, sont les valeurs lues dans
    le fichier bmp si la version de l'en-tête > 1. sinon valeur par defaut
    AlphaMask est lues dans le fichier bmp si la version de l'en-tête > 2, sinon valeur par defaut
    - Les valeurs de Shift et MaskSize sont calculées

    Ici je n'arrive pas à savoir comment le RawImage image du bitmap passe à 24bits ? ou plus
    précisément comment il determine l'AlphaShift à zero ?

    mon code de récupération des données pour le BitField:

    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
     
    Function TGLZBitmapBMPImage.GetHeaderRedMask: LongWord;
    Begin
      if FHeaderType>= bmpht_WindowsV2 then
      begin
        Case FHeaderType Of
            bmpht_WindowsV2: Result := LEToN(FInfoHeader.WindowsV2.biRedMask);
            bmpht_WindowsV3: Result := LEToN(FInfoHeader.WindowsV3.biRedMask);
            bmpht_WindowsV4: Result := LEToN(FInfoHeader.WindowsV4.biRedMask);
            bmpht_WindowsV5: Result := LEToN(FInfoHeader.WindowsV5.biRedMask);
        End;
      end
      else
      begin
        {$ifdef ENDIAN_BIG}
          Result := $0000FF00;
        {$else}
          Result :=$00FF0000;
        {$endif}
      end;
    End;
     
    Function TGLZBitmapBMPImage.GetHeaderGreenMask: LongWord;
    Begin
      if FHeaderType>= bmpht_WindowsV2 then
      begin
        Case FHeaderType Of
            bmpht_WindowsV2: Result := LEToN(FInfoHeader.WindowsV2.biGreenMask);
            bmpht_WindowsV3: Result := LEToN(FInfoHeader.WindowsV3.biGreenMask);
            bmpht_WindowsV4: Result := LEToN(FInfoHeader.WindowsV4.biGreenMask);
            bmpht_WindowsV5: Result := LEToN(FInfoHeader.WindowsV5.biGreenMask);
        End;
      end
      else
      begin
        {$ifdef ENDIAN_BIG}
           Result := $00FF0000;
        {$else}
           Result := $0000FF00;
        {$endif}
      end;
    End;
     
    Function TGLZBitmapBMPImage.GetHeaderBlueMask: LongWord;
    Begin
      if FHeaderType>= bmpht_WindowsV2 then
      begin
        Case FHeaderType Of
            bmpht_WindowsV2: Result := LEToN(FInfoHeader.WindowsV2.biBlueMask);
            bmpht_WindowsV3: Result := LEToN(FInfoHeader.WindowsV3.biBlueMask);
            bmpht_WindowsV4: Result := LEToN(FInfoHeader.WindowsV4.biBlueMask);
            bmpht_WindowsV5: Result := LEToN(FInfoHeader.WindowsV5.biBlueMask);
        End;
      end
      else
      begin
       {$ifdef ENDIAN_BIG}
          Result := $00FF0000;
       {$else}
          Result := $000000FF;
       {$endif}
      end;
    End;
     
    Function TGLZBitmapBMPImage.GetHeaderAlphaMask: LongWord;
    Begin
      if FHeaderType>= bmpht_WindowsV3 then
      begin
        Case FHeaderType Of
            bmpht_WindowsV3: Result := LEToN(FInfoHeader.WindowsV3.biAlphaMask);
            bmpht_WindowsV4: Result := LEToN(FInfoHeader.WindowsV4.biAlphaMask);
            bmpht_WindowsV5: Result := LEToN(FInfoHeader.WindowsV5.biAlphaMask);
          Else  Result:=0
        End;
      end
      else
      begin    
       {$ifdef ENDIAN_BIG}
           Result := $000000FF;
        {$else}
          Result := $FF000000;
        {$endif}
      end;
    End;
     
    ...
     
    function TGLZBitmapBMPImage.ReadImageProperties:Boolean; 
     
    	function GetMaskShift(AMask: LongWord): ShortInt;
    	begin
    	  Result := 0;
    	  while ((AMask and (1 shl Result)) = 0) and (Result < 32) do inc(Result);
    	 // if result = 32 then result:=0;
    	end;
     
    	function GetMaskSize(AMask: LongWord; AShift:ShortInt): Byte;
    	begin
    	  Result := 0;
    	  while (AShift + Result < 32) and ((AMask and (1 shl (AShift + Result))) <> 0) do Inc(Result);
    	end;
     
    begin
    ...
     
      { On a récupéré nos informations, on met à jour le  RawImage. de TGLZBitmap
         On charge la palette de couleur si besoins
         On initialise quelques variables utiles pour la lecture des données suivant
         le "PixelFormat"
       }
       With RawImage do
       begin
         UsedColors:=GetHeaderUsedColors;
         UsePalette:=False;
          With Description do
           begin
             // Le decalage par defaut pour le bitfield est le format de couleur (A)RGB
             (*RedShift := 16;
             GreenShift := 8;
             BlueShift := 24;
             AlphaShift :=0;RedMaskSize := 8;
             GreenMaskSize := 8;// Taille de valeur en Bit
             BlueMaskSize := 8;
             AlphaMaskSize := 8;*)
     
             // On Initialise le format de couleur gràce au "masque"
             // Format couleur par Defaut pour le BitField : ARGB
     
             RedMask := GetHeaderRedMask;
             GreenMask := GetHeaderGreenMask;
             BlueMask := GetHeaderBlueMask;
     
             RedShift := GetMaskShift(RedMask); //ShiftCount(RedMask);
             GreenShift := GetMaskShift(GreenMask);
             BlueShift := GetMaskShift(BlueMask);
     
             RedMaskSize :=  GetMaskSize(RedMask,RedShift);
             GreenMaskSize := GetMaskSize(GreenMask,GreenShift);
             BlueMaskSize := GetMaskSize(BlueMask,BlueShift);
     
             AlphaMask := 0; //GetMaskSize(AlphaMask);
             AlphaShift := 0;
             AlphaMaskSize :=0;
     
             if FHeaderType>bmpht_WindowsV2 then
             begin
               AlphaMask := GetHeaderAlphaMask;
               AlphaShift := GetMaskShift(AlphaMask);
               AlphaMaskSize := GetMaskSize(AlphaMask,AlphaShift);
             end
             else
             begin // En-tête Version 1, on initialise avec la valeur par defaut
              if BitCount = 32 then
              begin
              {$ifdef ENDIAN_BIG}
                AlphaMask := := $000000FF;
              {$else}
                AlphaMask := $FF000000;
              {$endif}
               AlphaShift := GetMaskShift(AlphaMask);
               AlphaMaskSize := GetMaskSize(AlphaMask,AlphaShift);
              end;
             end;
           end;
        ...
         FRowSize:=ComputeBytesPerLine(bmpWidth, bitCount, bleDWordBoundary);
         Case bitCount of  
    	 ...
           32:
           begin
             Description.ColorFormat:=cfBGRA;
     
             if Not(Compression=BMP_COMPRESSION_NONE) and not(Compression=BMP_COMPRESSION_BITF) then
             begin
               ShowMessage('Bad Compression');
               Result:=False;
             end;
     
             if Description.AlphaMaskSize > 0 then
             begin
               // Le Mask Alpha cache-t-il une autre composante de la couleur
                if (Description.RedMask or Description.GreenMask or Description.BlueMask) and Description.AlphaMask <> 0 then
                begin
                    Description.AlphaMask  := 0;
                    Description.AlphaShift := 0;
                    Description.AlphaMaskSize := 0;
                end;
            end;
    		// La taille du masque alpha est 0,. C'est un format 24bits.
            if Description.AlphaMaskSize = 0 then 
            begin
              //Description.ColorFormat:=cfBGR;
              BitCount:=24;//
              Description.AlphaMask  := $FF000000;
              Description.AlphaShift := 0;//GetMaskShift(Description.AlphaMask);
             // if  Description.AlphaShift = 24 then  Description.AlphaShift := 0;
            end;
           end;
         end;     
     
    procedure TGLZBitmapBMPImage.LoadFromMemory();
    var
    	YY,Y : Integer;
    	X:Integer;
    	DstColor: TGLZColor;
    	SrcPtr : PLongWord;
    	DstLine : PGLZColor;
    	SrcColor :LongWord;
    	LineBuffer : PByte;
     
    	function ExpandColor(Value: LongWord): TGLZColor;
    	var
    	tmpr, tmpg, tmpb, tmpa: LongWord;
    	begin
    		tmpr := value and RawImage.Description.RedMask;
    		tmpg := value and RawImage.Description.GreenMask;
    		tmpb := value and RawImage.Description.BlueMask;
    		tmpa := value and RawImage.Description.AlphaMask;
     
    		Result.Alpha := 255;
     
    		if RawImage.Description.RedShift < 0 then
    		  Result.Red := byte(tmpr shl (-RawImage.Description.RedShift))
    		else
    		  Result.Red := byte(tmpr shr RawImage.Description.RedbitShift);
     
    		if RawImage.Description.GreenShift < 0 then
    		  Result.Green := byte(tmpg shl (-RawImage.Description.GreenShift))
    		else
    		  Result.Green := byte(tmpg shr RawImage.Description.GreenShift);
     
    		if RawImage.Description.BluebitShift < 0 then
    		  Result.Blue := byte(tmpb shl (-RawImage.Description.BlueShift))
    		else
    		  Result.Blue := byte(tmpb shr RawImage.Description.BlueShift);
     
    		if  RawImage.Description.AlphaMaskSize>0 then
    		begin
    		  if RawImage.Description.AlphaShift < 0 then
    			Result.Alpha := byte(tmpa shl (-RawImage.Description.AlphaShift))
    		  else
    			Result.Alpha := byte(tmpa shr RawImage.Description.AlphaShift);
    		end; 
      end;
     
    begin
      // On initialise les dimensions de notre bitmap
      SetSize(bmpWidth, bmpHeight);
      Case RawImage.Description.PixelFormat of     
      ...
          pf32Bits:  // Pas de compression, formats couleurs suivant "BitField" sinon RGBA
          begin
            LineBuffer:=nil;
            ReallocMem(LineBuffer,FRowSize);
            Y:=0;
     
            repeat
              Memory.Read(LineBuffer^,FRowSize);
              if TopDown then YY:=Y else  YY:=MaxHeight-Y;
              if (Compression = BMP_COMPRESSION_BITF) then //LineDecodeBITFIELD32
              begin
                DstLine:=GetScanLine(YY);
     
                SrcPtr := PLongWord(LineBuffer);
                For X:=0 to MaxWidth do
                begin
                  SrcColor:=(SrcPtr+X)^;
                  DstColor := ExpandColor(SrcColor);
                  if (FHeaderType<bmpht_WindowsV3) then DstColor.Alpha:=255;
                  DstLine^:=DstColor;
                  Inc(DstLine);
                 end;
              end else LineDecodeBGRA32(LineBuffer,YY,false);
     
              Inc(Y);
            Until (Y>MaxHeight);
     
            ReAllocMem(LineBuffer, 0);
            FreeMem(LineBuffer);
            LineBuffer:=nil;
          end;
      end;
    end;

    2eme Cas avec les BMP encodés non standard et ou avec des erreurs d'encodage

    Exemples avec les fichiers BMP : rgb32h56.bmp et rbg32-xbgr.bmp, idem c'est ok ici

    Nom : rgba32h56-test1.jpg
Affichages : 743
Taille : 102,5 Ko

    Nom : rgb32-xbgr-test.jpg
Affichages : 723
Taille : 102,1 Ko

    Avec le fichier rgba32-1010102.bmp, paf

    Nom : rgba32-101002-test.jpg
Affichages : 730
Taille : 104,6 Ko

    Ici j'ai également essayé ça sans succes

    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
     
    { Counts how many bits are set }
    function MyCountBits(Value : byte) : shortint;
    var i,bits : shortint;
    begin
      bits:=0;
      for i:=0 to 7 do
      begin
        if (value mod 2)<>0 then inc(bits);
        value:=value shr 1;
      end;
      Result:=bits;
    end;
     
    { If compression is bi_bitfields, there could be arbitrary masks for colors.
      Although this is not compatible with windows9x it's better to know how to read these bitmaps
      We must determine how to switch the value once masked
      Example: 0000 0111 1110 0000, if we shr 5 we have 00XX XXXX for the color, but these bits must be the
      highest in the color, so we must shr (5-(8-6))=3, and we have XXXX XX00.
      A negative value means "shift left"  }
     
      /// ! \\\\ Provient de fpBMPReader que j'ai modifié
    function ShiftCountEx(Mask : longword; MaskSize:Byte) : shortint;
    var tmp : shortint;
    begin
      tmp:=0;
      if Mask=0 then
      begin
        Result:=0;
        exit;
      end;
     
      while (Mask mod 2)=0 do { rightmost bit is 0 }
      begin
        inc(tmp);
        Mask:= Mask shr 1;
      end;
      tmp:=tmp-(MaskSize-MyCountBits(Mask and $FF));
     // tmp:=tmp-(8-MyCountBits(Mask and $FF)); // CODE ORIGINAL
      Result:=tmp;
    end;  
     
    ...
    RedBitShift:=ShiftCountEx(RedMask,RedMaskSize);
    GreenBitShift:=ShiftCountEx(GreenMask,GreenMaskSize);
    BlueBitShift:=ShiftCountEx(BlueMask,BlueMaskSize);
     
    ...
     
     function ExpandColor(Value: LongWord): TGLZColor;
      var
        tmpr, tmpg, tmpb, tmpa: LongWord;
      begin
        tmpr := value and RawImage.Description.RedMask;
        tmpg := value and RawImage.Description.GreenMask;
        tmpb := value and RawImage.Description.BlueMask;
        tmpa := value and RawImage.Description.AlphaMask;
     
        Result.Alpha := 255; 
    	if RedbitShift < 0 then
    			 Result.Red := byte(tmpr shl (-RedbitShift))
    		   else
    			 Result.Red := byte(tmpr shr RedbitShift);
     
    		   if GreenbitShift < 0 then
    			 Result.Green := byte(tmpg shl (-GreenbitShift))
    		   else
    			 Result.Green := byte(tmpg shr GreenbitShift);
     
    		   if BluebitShift < 0 then
    			 Result.Blue := byte(tmpb shl (-BluebitShift))
    		   else
    			 Result.Blue := byte(tmpb shr BluebitShift);
     
    		  if  RawImage.Description.AlphaMaskSize>0 then
    		   begin
    			 if AlphabitShift < 0 then
    			   Result.Alpha := byte(tmpa shl (-AlphabitShift))
    			 else
    			   Result.Alpha := byte(tmpa shr AlphabitShift);
    		   end;
     
    	  end;
    idem resultat foireux

    Nom : rgba32-101002-test2.jpg
Affichages : 706
Taille : 104,6 Ko

    Valeurs des "BitShifts"
    Pour le fichier rgb32-xbgr.bmp

    [STATUS] Blue Mask = $FF000000
    [STATUS] Blue Mask = $00FF0000
    [STATUS] Blue Mask = $0000FF00
    [STATUS] Alpha Mask = $00000000

    [STATUS] Red Shift = 24
    [STATUS] Green Shift = 16
    [STATUS] Blue Shift = 8
    [STATUS] Alpha Shift = 32 //---> Ici l'alpha shift est "correct sans être juste"

    [STATUS] Red Size = 8
    [STATUS] Green Size = 8
    [STATUS] Blue Size = 8
    [STATUS] Alpha Size = 0

    ----> Nouvelles variable testés :

    [STATUS] Red Bit Shift = 24
    [STATUS] Green Bit Shift = 16
    [STATUS] Blue Bit Shift = 8
    [STATUS] Alpha Bit Shift = 0 //---> Ici l'alpha shift est correct

    [STATUS] BitCount = 24

    et celle de rgba32-1010102.bmp

    [STATUS] Blue Mask = $3FF00000
    [STATUS] Blue Mask = $000FFC00
    [STATUS] Blue Mask = $000003FF
    [STATUS] Alpha Mask = $C0000000

    [STATUS] Red Shift = 20
    [STATUS] Green Shift = 10
    [STATUS] Blue Shift = 0
    [STATUS] Alpha Shift = 30

    [STATUS] Red Size = 10
    [STATUS] Green Size = 10
    [STATUS] Blue Size = 10
    [STATUS] Alpha Size = 2
    [STATUS] BitCount = 32

    ----> Nouvelles variable testés :

    [STATUS] Red Bit Shift = 18
    [STATUS] Green Bit Shift = 8
    [STATUS] Blue Bit Shift = -2
    [STATUS] Alpha Bit Shift = 30

    [STATUS] BitCount = 32

    Si vous avez des idées ou une explications je suis perdu. Je suis sur que c'est tout bête mais je vois pas, je suis un peu perdu avec tous ces décalges de bits.

    Merci d'avance
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  2. #2
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Et je rajoute un 3eme cas de figure avec le fichier rgba32.bmp (dans les non standard)

    Affichage dans l'explorateur

    Nom : rgba32-ex.jpg
Affichages : 1010
Taille : 3,6 Ko

    Dans mon projet de test

    Nom : rgba32-test.jpg
Affichages : 1079
Taille : 99,8 Ko

    Alors c'est lequel qui est vraiment affiché correctement ? de l'explorateur et de TBitmap ?
    Sur ce coup je dirais TBitmap car c'est celui qui se rapproche le plus du fichier d'origine. Et vous ?

    Bref ça m'avance pas j'ai toujours par trouvé. C'est comme ci il me manquait une partie, un shr ou shl ou un petit truc dans le style mais je ne sais pas ou.
    Si c'est dans la function ExpandColor ou bien lorsque je calcul les décalages (Shift) ?
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Salut,


    Citation Envoyé par BeanzMaster Voir le message
    Qui aurait pensé que lire un simple fichier BMP soit si compliqué ?


    Merci pour les liens, je me marre en constatant qu'on marche dans les mêmes traces (Dr Dobbs je l'ai lu aussi )

    Un truc me chagrine, là :
    Citation Envoyé par BeanzMaster Voir le message
    - le fichier rgb32bf.bmp, paf

    Nom : rbg32bf-test1.jpg
Affichages : 1299
Taille : 102,1 Ko

    Avez-vous remarquez la valeur de "Depth" et d' "AlphaShift" pour le TBitmap ?
    Il le traite comme un 24bits !! et l'alphashift est à zero. Comparez avec "TGLZBitmap" à droite.

    Ici je n'arrive pas à savoir comment le RawImage image du bitmap passe à 24bits ? ou plus
    précisément comment il determine l'AlphaShift à zero ?
    Ou bien tu t'es fait des nœuds dans le code (pas de réinitialisation, autre embrouille), ou c'est le RawImage.Description qui patauge...
    Utilise le TBitmapInfoHeader, moi il me dit bien BitsPerPixel=32 pour les 3 fichiers rgb32xxx.bmp

    En plus on lit aussi BytesPerLine->384 et avec ma calculette, 384 c'est 127 x 3 (=381) + 3 donc fichier en 24 bits et padding de 3 bits.
    Y a comme un truc qui ne va pas, là.


    Citation Envoyé par BeanzMaster Voir le message
    2eme Cas avec les BMP encodés non standard et ou avec des erreurs d'encodage
    Oui mais là tu donnes le bâton pour te faire battre ! Même pas je les essaye ! J'ai bien vu qu'avec le navigateur comme avec l'aperçu de mon explorateur de fichiers, certains ne passent pas.
    Déjà que j'ai du mal avec des fichiers corrects !
    Tiens, à propos, merci pour le lien qui m'a fait découvrir cette suite de tests (j'étais passé à côté), ça m'a permis de confirmer un sale décalage avec FastSmoothResize sur la dernière ligne des rgb32.

    Quant à "BitFields", voilà ce qu'en dit Microsoft :
    Specifies that the bitmap is not compressed and that the color table consists of three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel. This is valid when used with 16- and 32-bpp bitmaps.
    Je n'ai pas regardé les autres fichiers.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  4. #4
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Citation Envoyé par BeanzMaster Voir le message
    Et je rajoute un 3eme cas de figure avec le fichier rgba32.bmp (dans les non standard)

    Affichage dans l'explorateur

    Nom : rgba32-ex.jpg
Affichages : 1010
Taille : 3,6 Ko

    Dans mon projet de test

    Nom : rgba32-test.jpg
Affichages : 1079
Taille : 99,8 Ko

    Alors c'est lequel qui est vraiment affiché correctement ? de l'explorateur et de TBitmap ?
    Sur ce coup je dirais TBitmap car c'est celui qui se rapproche le plus du fichier d'origine. Et vous ?
    "non standard", dossier "q" ? Voilà comment mon Linux le voit :
    Nom : dossier_q.png
Affichages : 1015
Taille : 2,4 Ko

    Mais il est tout pourri dans mon outil en test, développé sur un bête TBitmap et les routines de base (sauf RawImage ! )
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  5. #5
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jipété Voir le message
    "non standard", dossier "q" ? Voilà comment mon Linux le voit :
    Nom : dossier_q.png
Affichages : 1015
Taille : 2,4 Ko

    Mais il est tout pourri dans mon outil en test, développé sur un bête TBitmap et les routines de base (sauf RawImage ! )
    Ou c'est bien ça pour le q Merci pour le retour. C'est honteux Même l'explorateur de MICROSOFT avec son PROPRE FORMAT il se plante, quelle misère !!!
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  6. #6
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Salut,



    Merci pour les liens, je me marre en constatant qu'on marche dans les mêmes traces (Dr Dobbs je l'ai lu aussi )

    Un truc me chagrine, là :

    Ou bien tu t'es fait des nœuds dans le code (pas de réinitialisation, autre embrouille), ou c'est le RawImage.Description qui patauge...
    Utilise le TBitmapInfoHeader, moi il me dit bien BitsPerPixel=32 pour les 3 fichiers rgb32xxx.bmp

    En plus on lit aussi BytesPerLine->384 et avec ma calculette, 384 c'est 127 x 3 (=381) + 3 donc fichier en 24 bits et padding de 3 bits.
    Y a comme un truc qui ne va pas, là.



    Oui mais là tu donnes le bâton pour te faire battre ! Même pas je les essaye ! J'ai bien vu qu'avec le navigateur comme avec l'aperçu de mon explorateur de fichiers, certains ne passent pas.
    Déjà que j'ai du mal avec des fichiers corrects !
    Tiens, à propos, merci pour le lien qui m'a fait découvrir cette suite de tests (j'étais passé à côté), ça m'a permis de confirmer un sale décalage avec FastSmoothResize sur la dernière ligne des rgb32.

    Quant à "BitFields", voilà ce qu'en dit Microsoft :

    Je n'ai pas regardé les autres fichiers.

    Pour Depth on à déja discuté, dans ton fil de discussion le format est 32bits mais traité comme un 24bits
    Voila le code qui tue dans IntGraphics.Pas Ligne 5530 environ
    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
     
    procedure TLazReaderDIB.InternalRead(Stream: TStream; Img: TFPCustomImage);
    var
      Desc: TRawImageDescription;
      Depth: Byte;
    begin
      FContinue := True;
      Progress(psStarting, 0, False, Rect(0,0,0,0), '', FContinue);
      FImage := TheImage as TLazIntfImage;
      FIgnoreAlpha := True;
      Depth := 0;
      InternalReadHead;
     
      if FUpdateDescription
      then begin
        if (Info.BitCount = 32) and (Info.MaskSize.A = 0) // C'EST ICI QUE CA SE PASSE
        then Depth := 24
        else Depth := Info.BitCount;
        DefaultReaderDescription(Info.Width, Info.Height, Depth, Desc);
        FImage.DataDescription := Desc;
      end;
     
      InternalReadBody;
     
      // if there is no alpha in real (all alpha values = 0) then update the description
      if FUpdateDescription and FIgnoreAlpha and (Depth = 32) then
      begin
        Desc.AlphaPrec:=0;
        FImage.SetDataDescriptionKeepData(Desc);
      end;
     
      Progress(psEnding, 100, false, Rect(0,0,0,0), '', FContinue);
    end;
    Merci pour le lien
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  7. #7
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Yop !
    Citation Envoyé par BeanzMaster Voir le message
    Informations sur le format BMP :
    - http://www.drdobbs.com/the-bmp-file-...4409533?pgno=5
    Tu feras attention si tu étudies attentivement son article : je suis allé plus loin, j'ai récupéré son code source, ai pu le compiler (sous Linux, un peu galère c'est un vieux truc -- pas mon Linux, son code de 1995 !), ai pu l'exécuter (il plante grave : j'ai dû mettre en commentaire une libération de pointeur... Je verrai ça + tard avec le forum C) et j'ai constaté que son code ne gérait pas les fichiers 32 bits.
    Voilà.

    Citation Envoyé par BeanzMaster Voir le message
    Voilà le code qui tue dans IntfGraphics.Pas Ligne 5530 environ
    Quant à ça, surveiller cette nouvelle 1.8 sur la rampe de lancement ? Mais je n'y crois pas trop, je n'ai rien vu dans les release notes passées par Gilles,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  8. #8
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Citation Envoyé par Jipété Voir le message
    (il plante grave : j'ai dû mettre en commentaire une libération de pointeur... Je verrai ça + tard avec le forum C)
    Tiens, pour t'éviter de tomber dans le même piège que moi, suite petite discussion sur le forum C, voilà le début d'une fonction corrigée du fichier readbmp.c (environ ligne 700) :
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    int readSingleImageBMP(FILE *fp, RGB **argb, UINT32 *width, UINT32 *height)
    {
        BITMAPFILEHEADER  bfh;
        BITMAPHEADER      bh;
    //    RGB              *colorTable, *image;
        RGB              *colorTable = NULL;
        RGB              *image = NULL;
        int               rc, depth, inverted;
        long              numColors, numPixels, endPos;
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  9. #9
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Bonsoir,

    Apres quelques recherches avec du C, C++, C#, CC...C-....., (Merci Jipete ) et après m'être hypnotisé avec ça :




    Je suis tombé sur ça https://dxr.mozilla.org/mozilla-cent...BMPDecoder.cpp

    après quelques longues minutes et après une trentaine de test j'en suis arrivé là :

    En Jaune les fichiers que je lisais déja
    En Vert les nouveaux fichiers que j'arrive à lire
    En rouge le fichier QUE JE VEUX ABSOLUMENT ARRIVER A LIRE

    Je précise une chose j'affiche la même chose que l'explorateur Windows

    Nom : apercu_fichier_test_bmp32_ex3.jpg
Affichages : 664
Taille : 106,2 Ko

    ensuite le test avec le fichier rgba32-1010102.bmp

    Nom : rgba32-1010102--test.jpg
Affichages : 676
Taille : 103,1 Ko

    le fichier rgba32h52.bmp (oups il s'affiche pas dans l'explorateur )

    Nom : rgb32h52-test.jpg
Affichages : 700
Taille : 101,8 Ko


    et enfin les 3 fichiers qui pose problèmes

    Nom : rbg32bf-test2.jpg
Affichages : 693
Taille : 102,2 Ko
    Nom : rgb32-111110-test.jpg
Affichages : 682
Taille : 103,8 KoNom : rgb32-7187-test.jpg
Affichages : 658
Taille : 102,7 Ko

    Notez la version des en-têtes : toutes 1, et regardez le Depth et le PixelFormat dans les infos du TBitmap à gauche ! 24 !!!!!!

    Alors maintenant question je fais comment pour savoir comment appliquer le "bitfield" correctement (ou comment que ça se passe dans ce cas ? une idée quelqu'un ?

    Bref en attendant, Voila le nouveau code que j'utilise

    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
     
    ...
     
    Function TGLZBitmapBMPImage.GetHeaderRedMask: LongWord;
    Begin
      if FHeaderType>= bmpht_WindowsV2 then
      begin
        Case FHeaderType Of
            bmpht_WindowsV2: Result := LEToN(FInfoHeader.WindowsV2.biRedMask);
            bmpht_WindowsV3: Result := LEToN(FInfoHeader.WindowsV3.biRedMask);
            bmpht_WindowsV4: Result := LEToN(FInfoHeader.WindowsV4.biRedMask);
            bmpht_WindowsV5: Result := LEToN(FInfoHeader.WindowsV5.biRedMask);
        End;
      end
      else
      begin   
        {$ifdef ENDIAN_BIG}
          Result := $0000FF00;
        {$else}
          Result :=$00FF0000;
        {$endif}
      end;
    End;
     
    Function TGLZBitmapBMPImage.GetHeaderGreenMask: LongWord;
    Begin
      if FHeaderType>= bmpht_WindowsV2 then
      begin
        Case FHeaderType Of
            bmpht_WindowsV2: Result := LEToN(FInfoHeader.WindowsV2.biGreenMask);
            bmpht_WindowsV3: Result := LEToN(FInfoHeader.WindowsV3.biGreenMask);
            bmpht_WindowsV4: Result := LEToN(FInfoHeader.WindowsV4.biGreenMask);
            bmpht_WindowsV5: Result := LEToN(FInfoHeader.WindowsV5.biGreenMask);
        End;
      end
      else
      begin
        {$ifdef ENDIAN_BIG}
           Result := $00FF0000;
        {$else}
           Result := $0000FF00;
        {$endif}
      end;
    End;
     
    Function TGLZBitmapBMPImage.GetHeaderBlueMask: LongWord;
    Begin
      if FHeaderType>= bmpht_WindowsV2 then
      begin
        Case FHeaderType Of
            bmpht_WindowsV2: Result := LEToN(FInfoHeader.WindowsV2.biBlueMask);
            bmpht_WindowsV3: Result := LEToN(FInfoHeader.WindowsV3.biBlueMask);
            bmpht_WindowsV4: Result := LEToN(FInfoHeader.WindowsV4.biBlueMask);
            bmpht_WindowsV5: Result := LEToN(FInfoHeader.WindowsV5.biBlueMask);
        End;
      end
      else
      begin
       {$ifdef ENDIAN_BIG}
          Result := $00FF0000;
       {$else}
          Result := $000000FF;
       {$endif}
      end;
    End;
     
    Function TGLZBitmapBMPImage.GetHeaderAlphaMask: LongWord;
    Begin
      if FHeaderType>= bmpht_WindowsV3 then
      begin
        Case FHeaderType Of
            bmpht_WindowsV3: Result := LEToN(FInfoHeader.WindowsV3.biAlphaMask);
            bmpht_WindowsV4: Result := LEToN(FInfoHeader.WindowsV4.biAlphaMask);
            bmpht_WindowsV5: Result := LEToN(FInfoHeader.WindowsV5.biAlphaMask);
          Else  Result:=0
        End;
      end
      else
      begin
     
       {$ifdef ENDIAN_BIG}
           Result := $000000FF;
        {$else}
          Result := $FF000000;
        {$endif}
      end;
    End;
     
    ...
      function GetMaskShift(AMask: LongWord): ShortInt;
      begin
        Result := 0;
        while ((AMask and (1 shl Result)) = 0) and (Result < 32) do inc(Result);
        //if result = 32 then result:=0;
      end;
     
      function GetMaskSize(AMask: LongWord; AShift:ShortInt): Byte;
      begin
        Result := 0;
        while (AShift + Result < 32) and ((AMask and (1 shl (AShift + Result))) <> 0) do Inc(Result);
      end; 
    ...
     
      With RawImage do
       begin
         UsedColors:=GetHeaderUsedColors;
         UsePalette:=False;
     
         if BitCount>8 then
         begin
           With Description do
           begin
     
             // On Initialise le format de couleur gràce au "masque"
             // Format couleur par Defaut pour le BitField : ABGR
     
             RedMask := GetHeaderRedMask;
             GreenMask := GetHeaderGreenMask;
             BlueMask := GetHeaderBlueMask;
     
             RedShift := GetMaskShift(RedMask); //ShiftCount(RedMask);
             GreenShift := GetMaskShift(GreenMask);
             BlueShift := GetMaskShift(BlueMask);
     
             RedMaskSize :=  GetMaskSize(RedMask,RedShift);
             GreenMaskSize := GetMaskSize(GreenMask,GreenShift);
             BlueMaskSize := GetMaskSize(BlueMask,BlueShift);
     
             AlphaMask :=0;
             AlphaShift := 0;
             AlphaMaskSize :=0;
     
             if FHeaderType>bmpht_WindowsV2 then
             begin
               AlphaMask := GetHeaderAlphaMask;
               AlphaShift := GetMaskShift(AlphaMask);
               AlphaMaskSize := GetMaskSize(AlphaMask,AlphaShift);
             end
             else
             begin // En-tête Version 1, on initialise avec la valeur par defaut
              if BitCount = 32 then
              begin
              {$ifdef ENDIAN_BIG}
                AlphaMask := := $000000FF;
              {$else}
                AlphaMask := $FF000000;
              {$endif}
               AlphaShift := GetMaskShift(AlphaMask);
               AlphaMaskSize := GetMaskSize(AlphaMask,AlphaShift);
              end;
             end;
           end;
     
         end;        
    ...
      function GetBitFieldValue(Const Value : LongWord; Mask:LongWord; BitShift, BitSize : Byte): Byte;
      var
        I,J,v,v2 : Integer;
     
      begin
        V:=(Value and Mask) Shr BitShift;
        V2:=0;
        I:=8-BitSize;
        While I>0 do
        begin
          V2 := V2 or (V Shl I);
          I:=I-BitSize;
        end;
        if I<0 then
          V2 := V2 or (V Shr (-I))
        else
          V2 := V2 or (V Shl I);
     
        Result:=V2; // and 255;
     
      end;
     
    ...
     
    pf32Bits:  // Pas de compression, formats couleurs suivant "BitField" sinon format couleur par defaut BGRA
          begin
            LineBuffer:=nil;
            ReallocMem(LineBuffer,FRowSize);
            Y:=0;
            repeat
              Memory.Read(LineBuffer^,FRowSize);
              if TopDown then YY:=Y else  YY:=MaxHeight-Y;
              if (Compression = BMP_COMPRESSION_BITF) then
              begin
                DstLine:=GetScanLine(YY);
     
                SrcPtr := PLongWord(LineBuffer);
                For X:=0 to MaxWidth do
                begin
                  SrcColor:=(SrcPtr+X)^;
                  With RawImage.Description do
                  begin
                    DstColor.Red:= GetBitFieldValue(SrcColor,RedMask, RedShift, RedMaskSize);
                    DstColor.Green:= GetBitFieldValue(SrcColor,GreenMask, GreenShift, GreenMaskSize);
                    DstColor.Blue:= GetBitFieldValue(SrcColor,BlueMask, BlueShift, BlueMaskSize);
                  end;              
                  //if (FHeaderType<bmpht_WindowsV3) then
                  DstColor.Alpha:=255;
                  DstLine^:=DstColor;
                  Inc(DstLine);
                 end;
              end else LineDecodeBGRA32(LineBuffer,YY,false);
              Inc(Y);
            Until (Y>MaxHeight);
     
            ReAllocMem(LineBuffer, 0);
            FreeMem(LineBuffer);
            LineBuffer:=nil;
          end;
    Donc maintenant j'aimerais comprendre c'est à quel moment et surtout grâce à quelle(s) valeur(s) dans l'en-tête du fichier BMP qui me permettrait d'inialiser les variables "AlphaMaskSize" à 0 et l'"AlphaShift" à 0 ou 24 ?
    En gros c'est quand et comment qu'on sait que c'est du 24bit ? Ensuite on fait comment pour extraire la bonne valeur ? faut encore faire un autre petit décalage ou autre chose ?

    (AndNotOr si tu passe par là, je suis sure que tu pourras nous éclairer avec tous ces décalages de bits )

    Pas évident, mais suis déja content d'avoir le même affichage que Windows. Mais surtout en termes de performances, j'écrase le TBitmap


    Je continuer à chercher, je vais bien réussir à trouver !.
    Et je vais passer au 16bit çà devrait être une simple promenade de santé maintenant (enfin j'espère ! )

    A Bientôt
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  10. #10
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Yep !
    Citation Envoyé par BeanzMaster Voir le message
    En rouge le fichier QUE JE VEUX ABSOLUMENT ARRIVER A LIRE
    Comme ça, tu veux dire (de g. à dr. l'original, sa réduction et son agrandissement avec le filtre Bell) ?
    Nom : g_rgb32bf.png
Affichages : 648
Taille : 30,7 Ko

    Ou je n'ai pas compris ? Parce que tu VEUX ABSOLUMENT ARRIVER A LIRE ce fichier, et ligne dessous tu écris :
    Citation Envoyé par BeanzMaster Voir le message
    Je précise une chose j'affiche la même chose que l'explorateur Windows
    Alors ? T'affiches la même chose que l'explorateur mais t'arrives pas à le lire ? Un truc m'échappe, là...

    En attendant, voilà ce que je récupère dans le BitmapInfoHeader :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    FileName: /chemin/bmpsuite-2.5/g/rgb32bf.bmp
    (bih) Width    (pixels) : 127
    (bih) Height    (lines) : 64
    (bih) DatasSize (bytes) : 32512
    (bih) _Bits-per-Pixel   : 32
    (moi) Bytes-per-Pixel   : 4
    (moi) LineSize          : 508
    (moi) Pixels Mode       : RGBQuad
    (moi) Data Structure    : Down2Top
    (bih) Compression       : 3
    (bih) Color Table       : 0
    Les fichiers avec erreurs d'encodage ou de format je te laisse perdre du temps dessus.

    Citation Envoyé par BeanzMaster Voir le message
    Notez la version des en-têtes : toutes 1, et regardez le Depth et le PixelFormat dans les infos du TBitmap à gauche ! 24 !!!!!!
    Tu insistes avec RawImage.Description ? C'est pas fiable !

    Citation Envoyé par BeanzMaster Voir le message
    Alors maintenant question je fais comment pour savoir comment appliquer le "bitfield" correctement (ou comment que ça se passe dans ce cas ? une idée quelqu'un ?
    Même remarque que ligne précédente.

    Citation Envoyé par BeanzMaster Voir le message
    Donc maintenant j'aimerais comprendre c'est à quel moment et surtout grâce à quelle(s) valeur(s) dans l'en-tête du fichier BMP qui me permettrait d'inialiser les variables "AlphaMaskSize" à 0 et l'"AlphaShift" à 0 ou 24 ?
    En gros c'est quand et comment qu'on sait que c'est du 24bit ? Ensuite on fait comment pour extraire la bonne valeur ? faut encore faire un autre petit décalage ou autre chose ?
    Quant à ça, je n'ai pas creusé cette question car je ne trouve pas d'infos chez MSDN ; serait-ce spécifique aux routines FreePascal ?
    Pas d'idée sur la question.


    Et pour le reste je ne sais pas, je ne sais plus, je fatigue...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Bonjour,

    Hier soir, et pas que hier, j'écrivais ça :
    Citation Envoyé par Jipété Voir le message
    Tu insistes avec RawImage.Description ? C'est pas fiable !
    Peut-être que c'est moi qui ne sais pas l'utiliser, car ce matin, en farfouillant dans le code de l'unité ReSample.pas (trouvée, je le rappelle, dans le code de DoubleCommander), on peut lire ça, au tout début de la procédure de stretch :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
        if Src.RawImage.Description.AlphaPrec = 0 then // if bitmap has not alpha channel
          SrcIntfImage := CreateAlphaFromMask(Src)
        else
          SrcIntfImage := TLazIntfImage.Create(Src.RawImage, False);
        DstIntfImage := TLazIntfImage.Create(Dst.RawImage, False);
        ImgFormatDescription.Init_BPP32_B8G8R8A8_BIO_TTB(DstWidth, DstHeight);
        DstIntfImage.DataDescription := ImgFormatDescription;
    Et jusqu'à présent cette unité fonctionne correctement.

    À bon entendeur, salut !
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  12. #12
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Yep !

    En attendant, voilà ce que je récupère dans le BitmapInfoHeader :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    FileName: /chemin/bmpsuite-2.5/g/rgb32bf.bmp
    (bih) Width    (pixels) : 127
    (bih) Height    (lines) : 64
    (bih) DatasSize (bytes) : 32512
    (bih) _Bits-per-Pixel   : 32
    (moi) Bytes-per-Pixel   : 4
    (moi) LineSize          : 508
    (moi) Pixels Mode       : RGBQuad
    (moi) Data Structure    : Down2Top
    (bih) Compression       : 3
    (bih) Color Table       : 0
    Les fichiers avec erreurs d'encodage ou de format je te laisse perdre du temps dessus.
    On a la même chose

    Citation Envoyé par Jipété Voir le message
    Tu insistes avec RawImage.Description ? C'est pas fiable !
    Le RawImage.Description que tu vois dans le code posté c'est mon mien à moi, aucun lien de parenté avec le RawImage de TBitmap. Si ce n'est que le nom. Qui je l'avoue peux porter à confusion

    Citation Envoyé par Jipété Voir le message

    Comme ça, tu veux dire (de g. à dr. l'original, sa réduction et son agrandissement avec le filtre Bell) ?

    Ou je n'ai pas compris ? Parce que tu VEUX ABSOLUMENT ARRIVER A LIRE ce fichier, et ligne dessous tu écris :

    Alors ? T'affiches la même chose que l'explorateur mais t'arrives pas à le lire ? Un truc m'échappe, là...
    Ce fichier rgb32bf.bmp (et les 2 autres) je n'arrive pas à les afficher correctement. comme tu peux le voir sur mes captures. Le fichier rgb32bf fait partie (sois-disant des 100% correct) c'est pour ça que je veux absolument arriver a le lire.
    Pour les autres, ceux que j'arrive à afficher (entourés vert et jaune) mon affichage est le même que dans l'explorateur.

    Les points commun des 3 fichiers qui me posent problème :
    - Version en-tête Windows V1 donc sans paramètres de masque à extraire
    - Le rawImage du TBitmap donne un pixelformat pf24bit et le depth également à 24

    Pour moi le fichier rgb32bf.bmp n'a rien à faire dans la liste des "100% Correct" il n'est pas encodé correctement par rapport aux spécifications.
    L'explorateur et TBitmap arrivent pourtant à les afficher, eux. Donc, doit bien avoir quelque chose qui fait que ? non ?

    Ce fichier à bien BitPerPixel à 32 dans l'en-tête.
    Si tu compares avec le fichier rgb32bfDef.Bmp (correctement encodé) avec les masques de couleurs par defaut "BGRA" pas de soucis. Le TBitmap lui aussi, le reconnait bien avec le pixelformat à pf32bits (voir capture dans mon 1er message)
    Alors qu'avec rgb32bf.bmp le Tbitmap le reconnait comme avec un pf24bits.

    Ensuite les autres différences que l'on peux voir, entre ces 2 fichiers ce sont dans le TBitmap les valeurs de AlphaPrec et AlphaShift.
    Respectivement, Pour moi, mes valeurs à droite sont AlphaMaskSize et AlphaShift
    Pour le fichier rgb32bfdef.bmp avec TBitmap les valeurs de AlphaPrec et AlphaShift. sont 0 et 24. Chez moi toujours 8 et 24
    Dans rgb32bf.bmp et les 2 autres fichiers qui posent problème, avec TBitmap on peux remarquer que les valeurs de AlphaPrec et AlphaShift. sont 0 et 0. Chez moi elle sont toujours de 8 et 24.


    C'est un truc bien tordu quand même. Surement un truc tout bête et tout logique, mais j'arrive pas à mettre le doigt dessus et à comprendre

    Donc la question que je me pose c'est comment initialiser correctement mes valeurs AlphaMaskSize et AlphaShift ? C'est à quel niveau que ça se passe, elle est ou cette petite différence entre rgb32bf.bmp et rgb32bfdef.bmp ?
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  13. #13
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Citation Envoyé par BeanzMaster Voir le message
    Pour moi le fichier rgb32bf.bmp n'a rien à faire dans la liste des "100% Correct" il n'est pas encodé correctement par rapport aux spécifications.
    L'explorateur et TBitmap arrivent pourtant à les afficher, eux. Donc, doit bien avoir quelque chose qui fait que ? non ?
    Je te trouve bien sévère !
    Vu de mon côté et avec mes outils, ce fichier est parfait...
    Nom : infos_rgb32bf.bmp.png
Affichages : 1022
Taille : 23,5 Ko

    La vue hexa montre bien un pf à 32 bits (adresse 1C, 20hex) et il n'y a pas de compression (1E à 00hex)

    Kess tu veux de plus ?

    Citation Envoyé par BeanzMaster Voir le message
    Alors qu'avec rgb32bf.bmp le Tbitmap le reconnait comme avec un pf24bits.
    Oui, il y a un souci dans ton outil.
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  14. #14
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Je te trouve bien sévère !
    Vu de mon côté et avec mes outils, ce fichier est parfait...
    Nom : infos_rgb32bf.bmp.png
Affichages : 1022
Taille : 23,5 Ko

    La vue hexa montre bien un pf à 32 bits (adresse 1C, 20hex) et il n'y a pas de compression (1E à 00hex)

    Kess tu veux de plus ?


    Oui, il y a un souci dans ton outil.
    Sauf que la c'est rgb32.bmp que tu me montres pas rgb32bf.bmp. Pour le rgb32.bmp j'ai pas de soucis
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  15. #15
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Bon j'en avais marre du coup j'ai été maté le code source de bmpsuite qui génère ces fichiers :

    Code C : 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
    	defaultbmp(glctx, c);
    	c->filename = "g/rgb32bfdef.bmp";
    	c->bpp = 32;
    	c->compression = BI_BITFIELDS;
    	c->pal_entries = 0;
    	c->bf[I_R] = 0x00ff0000; c->nbits[I_R] = 8; c->bf_shift[I_R] = 16;
    	c->bf[I_G] = 0x0000ff00; c->nbits[I_G] = 8; c->bf_shift[I_G] = 8;
    	c->bf[I_B] = 0x000000ff; c->nbits[I_B] = 8; c->bf_shift[I_B] = 0;
    	c->bitfieldssize = 12;
    	set_calculated_fields(c);
    	if(!make_bmp_file(c)) goto done;
     
    	defaultbmp(glctx, c);
    	c->filename = "g/rgb32bf.bmp";
    	c->bpp = 32;
    	c->compression = BI_BITFIELDS;
    	c->pal_entries = 0;
    	c->bf[I_R] = 0xff000000; c->nbits[I_R] = 8; c->bf_shift[I_R] = 24;
    	c->bf[I_G] = 0x00000ff0; c->nbits[I_G] = 8; c->bf_shift[I_G] = 4;
    	c->bf[I_B] = 0x00ff0000; c->nbits[I_B] = 8; c->bf_shift[I_B] = 16;
    	c->bitfieldssize = 12;
    	set_calculated_fields(c);
    	if(!make_bmp_file(c)) goto done;


    le 1er truc qui saute au yeux ce sont bien sur les valeurs et bf[] bf_shift[]

    c->bf[I_R] = 0xff000000; c->bf_shift[I_R] = 24;
    c->bf[I_G] = 0x00000ff0; c->bf_shift[I_G] = 4;
    c->bf[I_B] = 0x00ff0000; c->bf_shift[I_B] = 16;

    Comment je dois faire pour déterminer les bonnes valeurs des masque et shift ? c'est quoi ce bit de plus en violet ?

    Ce dont je suis sur
    L'en-tête de ces fichiers bmp est la 1, donc pas de paramètres pour les masques à lire.
    Suivant la spécification du format bmp le bitfield est par défaut égal au format de couleur ARGB ce qui est bien le cas du fichier c->filename = "g/rgb32bfdef.bmp" nb: attention les masque sont stockés sous le format BIG-ENDIAN dans les en-têtes


    donc par défaut, le masque alpha = 0xff000000, et le shift=0 et sa taille qui doit être mise à 0, car à la base la version ne supportait pas le format de pixel 32bits.
    cf wikipedia "In the original OS/2 DIB, the only four legal values of color depth were 1, 4, 8, and 24 bits per pixel (bpp).[4] Contemporary DIB Headers allow pixel formats with 1, 2, 4, 8, 16, 24 and 32 bits per pixel (bpp).[16] GDI+ also permits 64 bits per pixel.[17]"

    Donc pour le fichier c->filename = "g/rgb32bf.bmp"; c'est quoi la formule magique pour trouver les bon Shift ???? c'est à dire 24,4,16 et donc pour le alpha 8 + comment déterminer ce bit en plus????
    Faut tester le 1er pixel ? J'ai rien vu de tel jusque là dans les sources de la LCL. Donc grande question : Comment TBitmap, TLazIntImage font pour afficher correctement ce fichier (et les autres) ?
    Comment déterminer les bonnes valeurs ?
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  16. #16
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Citation Envoyé par BeanzMaster Voir le message
    Sauf que la c'est rgb32.bmp que tu me montres pas rgb32bf.bmp. Pour le rgb32.bmp j'ai pas de soucis


    Autant pour moi (ai passé les trois quarts de la journée à me battre avec les options des filtres de resampling, ça aussi c'est quelque chose !), bref, avec rgb32bf.bmp on a l'information BI_BITFIELDS (03hex @ 1E) :
    Nom : rgb32bf.png
Affichages : 637
Taille : 2,0 Ko


    Citation Envoyé par BeanzMaster Voir le message
    Donc pour le fichier c->filename = "g/rgb32bf.bmp"; c'est quoi la formule magique pour trouver les bon Shift ???? c'est à dire 24,4,16 et donc pour le alpha 8 + comment déterminer ce bit en plus????
    Faut tester le 1er pixel ? J'ai rien vu de tel jusque là dans les sources de la LCL. Donc grande question : Comment TBitmap, TLazIntImage font pour afficher correctement ce fichier (et les autres) ?
    Comment déterminer les bonnes valeurs ?
    Peut-être en réussissant à comprendre ce charabia ? :
    If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member of BITMAPINFO contains three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel. Each DWORD in the bitmap array represents a single pixel.

    When the biCompression member is BI_BITFIELDS, bits set in each DWORD mask must be contiguous and should not overlap the bits of another mask. All the bits in the pixel do not need to be used.
    en provenance directe de la bible...
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  17. #17
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jipété Voir le message


    Autant pour moi (ai passé les trois quarts de la journée à me battre avec les options des filtres de resampling, ça aussi c'est quelque chose !), bref, avec rgb32bf.bmp on a l'information BI_BITFIELDS (03hex @ 1E) :
    Pas de soucis ça m'arrive aussi

    Citation Envoyé par Jipété Voir le message
    Peut-être en réussissant à comprendre ce charabia ? :
    If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member of BITMAPINFO contains three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel. Each DWORD in the bitmap array represents a single pixel.

    When the biCompression member is BI_BITFIELDS, bits set in each DWORD mask must be contiguous and should not overlap the bits of another mask. All the bits in the pixel do not need to be used.
    en provenance directe de la bible...
    Un grand merci JP, j'étais passé à coté en m'accrochant aux definitions des en-têtes. Et je me suis mis dedans aussi à cause d'une Variable nommée "MaskSize"dans la LCL et dans d'autre fichiers.
    J'ai fait le rapprochement avec ce code de bmpsuite et c->bitfieldssize

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    static void write_bitfields(struct context *c)
    {
    	size_t offs;
    	if(c->bitfieldssize!=12 && c->bitfieldssize!=16) return;
    	offs = 14+c->headersize;
    	set_uint32(c,offs  ,c->bf[I_R]);
    	set_uint32(c,offs+4,c->bf[I_G]);
    	set_uint32(c,offs+8,c->bf[I_B]);
    	if(c->bitfieldssize==16) {
    		set_uint32(c,offs+12,c->bf[I_A]);
    	}
    }
    Et aussi le fait qu'il pouvait y avoir un espace perdu après l'en-tête cf https://upload.wikimedia.org/wikiped...fileFormat.png GAP1 que j'avais oublié

    Après quelques recherche sur bmiColors (qui est normalement l'espace réservé à la palette de couleur, dans le cas d'un fichier bmp indexé) et vérification de la taille de cet espace "perdu", tiptop tout fonctionne à merveille
    Suffisait de lire les masques RGB ou RGBA en fonction de la taille de l'espace perdu et si l'en-tête est la version 1. (nb ici les masque sont enregistrés dans le fichier en Little-Endian)

    Nom : rbg32bf-test3ok.jpg
Affichages : 685
Taille : 101,9 Ko

    Voila l'explications pourquoi le TBitmap le voie comme un 24bit, si le GapSize = 0 ou 12 c'est du 24bits si c'est 16 c'est bien un 32bits

    Bref un grand merci encore JP

    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  18. #18
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    10 730
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 10 730
    Points : 15 132
    Points
    15 132
    Par défaut
    Salut, et félicitations

    Bien joué !

    Citation Envoyé par BeanzMaster Voir le message
    Et aussi le fait qu'il pouvait y avoir un espace perdu après l'en-tête cf https://upload.wikimedia.org/wikiped...fileFormat.png GAP1 que j'avais oublié
    N'oublie pas non plus le GAP2,

    Et où peut-on trouver des infos plus précises que cette image qui ne nous dit rien, à propos de ces gaps ?

    Sinon, juste une bricole qui m'a interpellé, tu feras attention à ne pas te prendre les pieds dans le tapis, c'est un coup à rater une marche :

    Nom : ordrelignes.png
Affichages : 619
Taille : 26,6 Ko

    Bonne journée,
    Il a à vivre sa vie comme ça et il est mûr sur ce mur se creusant la tête : peutêtre qu'il peut être sûr, etc.
    Oui, je milite pour l'orthographe et le respect du trait d'union à l'impératif.
    Après avoir posté, relisez-vous ! Et en cas d'erreur ou d'oubli, il existe un bouton « Modifier », à utiliser sans modération
    On a des lois pour protéger les remboursements aux faiseurs d’argent. On n’en a pas pour empêcher un être humain de mourir de misère.
    Mes 2 cts,
    --
    jp

  19. #19
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par Jipété Voir le message
    Salut, et félicitations

    Bien joué !
    N'oublie pas non plus le GAP2,
    Merci sans toi j'aurais pas fais le lien avant un bon moment je pense

    Citation Envoyé par Jipété Voir le message
    Et où peut-on trouver des infos plus précises que cette image qui ne nous dit rien, à propos de ces gaps ?
    Mise à part dans le Wiki ou on peux trouver ci-dessous (et dans quelques commentaires ou ligne de code dans des sources comme Vampyre, Gr32, OPBitmap64...) je n'ai pas trouvé grand chose.

    Referring to the diagram 1, the bitmap file is composed of structures in the following order:

    Structure name Optional Size Purpose Comments

    Color table Semi-optional Variable-size To define colors used by the bitmap image data (Pixel array) Mandatory for color depths ≤ 8 bits
    Gap1 Yes Variable-size Structure alignment An artifact of the File offset to Pixel array in the Bitmap file header
    Pixel array No Variable-size To define the actual values of the pixels The pixel format is defined by the DIB header or Extra bit masks. Each row in the Pixel array is padded to a multiple of 4 bytes in size
    Gap2 Yes Variable-size Structure alignment An artifact of the ICC profile data offset field in the DIB header
    ICC colorprofile Yes Variable-size To define the color profile for color management
    Can also contain a path to an external file containing the color profile. When loaded in memory as "non-packed DIB", it is located between the color table and Gap1.

    Qui nous renvoi ici

    et ou il y à ça !

    The red, green, and blue bitfield masks for BI_BITFIELD bitmaps immediately follow the BITMAPINFOHEADER, BITMAPV4HEADER, and BITMAPV5HEADER structures. The BITMAPV4HEADER and BITMAPV5HEADER structures contain additional members for red, green, and blue masks as follows.
    Member Meaning
    RedMask Color mask that specifies the red component of each pixel, valid only if the Compression member is set to BI_BITFIELDS.
    GreenMask Color mask that specifies the green component of each pixel, valid only if the Compression member is set to BI_BITFIELDS.
    BlueMask Color mask that specifies the blue component of each pixel, valid only if the Compression member is set to BI_BITFIELDS.

    When the biCompression member of BITMAPINFOHEADER is set to BI_BITFIELDS and the function receives an argument of type LPBITMAPINFO, the color masks will immediately follow the header. The color table, if present, will follow the color masks. [B]BITMAPCOREHEADER bitmaps do not support color masks[/B].
    Alors en gros si je comprend bien avec les version des en-tête de 1, 4 et 5 les Masques de couleur CORRECT à prendre en charge son ceux juste apres l'en-tete (GAPSize 1) mais qu'a partir de la 4 et 5 il existes d'autres valeurs additionnel pour les masques et que en gros eux ils servent à rien si le gapsize = 12 ou 16 . Sauf que Microsoft considère qu'un fichier BMP est correctement encodé avec les versions 4 et 5 si les masques sont ceux des en-tête et non ceux du "GapSize". On le voie dans l'explorateur (les fichiers ou le "BMP" est affiché en vert et rouge) alors vous en pensez quoi de celle la ?

    Citation Envoyé par Jipété Voir le message
    Sinon, juste une bricole qui m'a interpellé, tu feras attention à ne pas te prendre les pieds dans le tapis, c'est un coup à rater une marche :

    Bonne journée,
    Ca j'en tiens même pas compte à ce niveau c'est la sauce graphique de la LCL (Je me demande pourquoi ils ont nommées la classe TRawImage, TRawImage ? Il n'y a plus rien de Brut là dedans ! )

    Note : Je m'en sert juste comme référence et pour faire des comparatifs. Et tout n'est pas si mauvais dedans )

    Me reste tout de même à percer ce mystère d'impression d'affichage correct dans TBitmap :
    Nom : rgba32-1010102-testok.jpg
Affichages : 263
Taille : 103,2 Ko

    Mais bon je verrais ça plus tard je vais continuer avec le 16,8,4,2 et 1 bit(s)

    Merci A+
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

  20. #20
    Expert confirmé
    Avatar de BeanzMaster
    Homme Profil pro
    Amateur Passionné
    Inscrit en
    Septembre 2015
    Messages
    1 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Amateur Passionné
    Secteur : Tourisme - Loisirs

    Informations forums :
    Inscription : Septembre 2015
    Messages : 1 899
    Points : 4 346
    Points
    4 346
    Billets dans le blog
    2
    Par défaut
    Citation Envoyé par BeanzMaster Voir le message
    Me reste tout de même à percer ce mystère d'impression d'affichage correct dans TBitmap :
    ...
    Mais bon je verrais ça plus tard je vais continuer avec le 16,8,4,2 et 1 bit(s)

    Salut à tous me revoilà, (cela a été plus vite que prévu ! ) J'ai trouvé (du moins pour Windows. Pour Linux ben heu, je ne sais pas)

    Une fois que je pouvais lire tout ces fichiers j'ai voulu tester l'affichage avec prise en charge de la transparence et voila le résultat :

    Nom : rgba32fakealpha-test1ok.jpg
Affichages : 663
Taille : 99,8 KoNom : rgba32-1010102-testok2.jpg
Affichages : 612
Taille : 103,0 Ko

    Ce qui est drôle maintenant c'est çà :

    Nom : rgba32h56-test2ok.jpg
Affichages : 637
Taille : 102,3 Ko

    Là c'est le TBitmap qui se plante! Regardez le pixelformat et le depth du RawImage de TBitmap à gauche. Y'a pas photo là y a vraiment un problème avec la gestion du graphisme avec fpc et lazarus

    Mystère résolu ! un fichier Bitmap 32bit il faut l'afficher avec transparence pour qu'il puisse être rendu correctement.

    Doc par Ici, par et encore au-delà ou on trouve l'information la plus importante :

    Note that the APIs use premultiplied alpha, which means that the red, green and blue channel values in the bitmap must be premultiplied with the alpha channel value. For example, if the alpha channel value is x, the red, green and blue channels must be multiplied by x and divided by 0xff prior to the call.
    Pour info j'affiche le TBitmap comme ceci :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Panel1.Canvas.Draw(0,0,Bitmap1);
    Ma solution, pour afficher mon Bitmap pour Windows est la suivante :

    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
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    Type TGLZColor = packed record // Pour Linux Red, Green, Blue, Alpha
              Blue, Green, Red, Alpha : Byte;
           end;
          PGLZColor = ^TGLZColor;
     
    var
      PreMultipliedAlphaLUT: array[0..255,0..255] of  Byte;  
     
    procedure DrawGLZBitmapToCanvas(ABmp:TGLZCustomBitmap; Canvas: TCanvas;R:Types.TRect; Const Opaque:Boolean=true;Const ClearBk : Boolean=false);
    {$IFDEF WINDOWS}
    Var
      BitsInfo: TBitmapInfo;
      //RW,RH : Integer;
      hBmp: HBitmap;
      memDC: HDC;
      hOld: HGDIOBJ;
      BitsPtr: Pointer;
      PixPtr:PGLZColor;
      DataSize: integer;
      bf: TBlendFunction;
     
      procedure DoPreMultipliedTable;
      var
        i:integer;
        DstPtr, SrcPtr :PGLZColor;
      begin
        i:=0;
        SrcPtr:= aBmp.GetScanLine(0);
        DstPtr:=PGLZColor(BitsPtr);
        repeat
          DstPtr^.Blue := PreMultipliedAlphaLUT[SrcPtr^.Blue][SrcPtr^.Alpha];
          DstPtr^.Green := PreMultipliedAlphaLUT[SrcPtr^.Green][SrcPtr^.Alpha];
          DstPtr^.Red := PreMultipliedAlphaLUT[SrcPtr^.Red][SrcPtr^.Alpha];  
          DstPtr^.Alpha := SrcPtr^.Alpha;
          Inc(SrcPtr);
          Inc(DstPtr);
          Inc(i);
        until i>ABmp.MaxSize;
      end;
     
    Begin
     
     With BitsInfo.bmiHeader Do
     Begin
       biSize := SizeOf(TBitmapInfoHeader);
       biWidth :=ABmp.Width; // ABmp.RawImage.Image..Width;
       biHeight := -ABmp.Height; //-ABmp.RawImage.Image.Height; { Note: Une hauteur negative signifie que la lecture d'une ligne se fait de bas en haut }
       biPlanes := 1;
       biBitCount := 32; //On Affiche en 32bits (normalent prendre donnée depuis "Device"
       biCompression := BI_RGB;
       biSizeImage :=  (ABmp.Width*ABmp.Height)*4; //ABmp.RawImage.Image.Size;
       biXPelsPerMeter := 0;
       biYPelsPerMeter := 0;
       biClrUsed := 0;
       biClrImportant := 0;
      End;
     
      if Opaque then
      begin
        Canvas.Lock;
        if ClearBk then Canvas.Clear;
     
        Windows.StretchDIBits(Canvas.Handle,
                      R.Left, R.Top, (R.Right-R.Left), (R.Bottom-R.Top),
                      0, 0, aBmp.Width, aBmp.Height,  PByte(ABmp.GetBitmapData),  //ABmp.RawImage.Image.Data,
                      BitsInfo, DIB_RGB_COLORS, SRCCOPY);
     
        // NOTE : Le resultat de ABmp.GetBitmapData est de type PGLZColor
        Canvas.Unlock;
      end
      else
      begin
        BitsPtr:=nil;
     
        // On doit inverser notre d'affichage de haut en bas à de bas en haut
        PixPtr:=aBmp.GetScanLine(0);
        DataSize:=ABmp.Width*4; //((BitsInfo.bmiHeader.biWidth * BitsInfo.bmiHeader.biBitCount + 31 ) shr 5 ) shl 2;
        DataSize:=DataSize * -BitsInfo.bmiHeader.biHeight;
     
        memDC := CreateCompatibleDC(Canvas.Handle);
        hBmp := Windows.CreateDIBSection(Canvas.Handle, BitsInfo, DIB_RGB_COLORS,BitsPtr,0,0);
        DoPreMultipliedTable;
        //Move(PixPtr^, BitsPtr^, DataSize);
        hOld  := SelectObject(memDC, hBMp);
        With bf do
        begin
          BlendOp := AC_SRC_OVER;
          BlendFlags := 0;
          SourceConstantAlpha := $FF;
          AlphaFormat := AC_SRC_ALPHA;
        end;
        Canvas.Lock;
        Win32Extra.AlphaBlend(Canvas.Handle,
          R.Left, R.Top, (R.Right-R.Left), (R.Bottom-R.Top),
          memDC,
          0, 0, aBmp.Width, aBmp.Height,bf);
        Canvas.Unlock;
     
        SelectObject(MemDC, hOld);
        DeleteDC(memDC);
        DeleteObject(hBMp);
       end;
    End;
     
    procedure ComputePreMulAlphaLUT;
    var
      i,j:Integer;
    begin
     for i:=0 to 255 do
       for j:=0 to 255 do
         PreMultipliedAlphaLUT[I][J]:=Byte(Round(i*j /255));
    end;
     
    initialization
    {$IFDEF WINDOWS}
     ComputePreMulAlphaLUT;
    {$ENDIF}
    A+
    • "L'Homme devrait mettre autant d'ardeur à simplifier sa vie qu'il met à la compliquer" - Henri Bergson
    • "Bien des livres auraient été plus clairs s'ils n'avaient pas voulu être si clairs" - Emmanuel Kant
    • "La simplicité est la sophistication suprême" - Léonard De Vinci
    • "Ce qui est facile à comprendre ou à faire pour toi, ne l'est pas forcément pour l'autre." - Mon pèrei

    Mes projets sur Github - Blog - Site DVP

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Probleme avec encodage de simple quote
    Par linkowich dans le forum Langage
    Réponses: 2
    Dernier message: 31/10/2005, 13h16
  2. Réponses: 2
    Dernier message: 15/04/2004, 15h44

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