udfBMPInfo
str udfBMPInfo (str)
;------------------------------------------------------------------------------------------------------------------------------------------
#DefineFunction udfBMPInfo (strFileBMP)
If FileExist (strFileBMP) != 1 Then Return -1
intFileSize = FileSize (strFileBMP)

; Read file header.
intBMP_FileHeaderSize = 14
If intFileSize < intBMP_FileHeaderSize Then Return -3
hdlBB = BinaryAlloc (intBMP_FileHeaderSize)
BinaryReadEx (hdlBB, 0, strFileBMP, 0, intBMP_FileHeaderSize)

; Check BMP identifier, should be "BM" for Windows 3.1x, 95, NT, ...
If "BM" != BinaryPeekStr (hdlBB, 0, 2) Then Return -2

; Check BMP internal filesize, should be same size as FileSize (strFileBMP) otherwise BMP file seems to be corrupted.
If intFileSize != BinaryPeek4 (hdlBB, 2) Then Return -3

; BMP_Reserved   = BinaryPeek4(hdlBB ,6)
; BMP_DataOffset = BinaryPeek4(hdlBB ,10) ; Offset from beginning of file to the beginning of the bitmap data.
; BMP_InfoHeaderSize = BinaryPeek4(hdlBB ,14) ; Length of the Bitmap Info Header used to describe the bitmap colors, compression, ...
hdlBB = BinaryFree (hdlBB)

; Read infoheader
intBMP_InfoHeaderSize = 40 ; Windows specific BMP.
hdlBB = BinaryAlloc (intBMP_InfoHeaderSize)
BinaryReadEx (hdlBB, 0, strFileBMP, intBMP_FileHeaderSize, intBMP_InfoHeaderSize)

; Build list with BMP properties from infoheader.
strList = BinaryPeek4 (hdlBB, 4) ; BMP_Width.
strList = strList : @TAB : BinaryPeek4 (hdlBB, 8) ; BMP_Height.
strList = strList : @TAB : BinaryPeek2 (hdlBB, 12) ; BMP_Planes.
strList = strList : @TAB : BinaryPeek2 (hdlBB, 14) ; BMP_BPP.
strList = strList : @TAB : BinaryPeek4 (hdlBB, 16) ; BMP_Compression.
strList = strList : @TAB : BinaryPeek4 (hdlBB, 20) ; BMP_SizeImage.
strList = strList : @TAB : BinaryPeek4 (hdlBB, 24) ; BMP_XPixPerMeter.
strList = strList : @TAB : BinaryPeek4 (hdlBB, 28) ; BMP_YPixPerMeter.

; Special handling for zero value, possibly not needed.
intBMP_ClrUsed = BinaryPeek4 (hdlBB, 32) ; BMP_ClrUsed.
If intBMP_ClrUsed == 0 Then intBMP_ClrUsed = 2 ** BinaryPeek2 (hdlBB, 14)
strList = strList : @TAB : intBMP_ClrUsed

; Special handling for zero value, possibly not needed.
intBMP_ClrImportant = BinaryPeek4 (hdlBB, 36) ; BMP_ClrImportant.
If intBMP_ClrImportant == 0 Then intBMP_ClrImportant = 2 ** BinaryPeek2 (hdlBB, 14)
strList = strList : @TAB : intBMP_ClrImportant

hdlBB = BinaryFree (hdlBB)

Return strList
;..........................................................................................................................................
; Returns a list of BMP file properties as a tab delimited string, e.g. "3456|2432|1|1|0|1050624|0|0|2|2".
; Returns -1 on error if input file does not exist or cannot be accessed.
; Returns -2 on error if input file fails "BM" identifier.
; Returns -3 on error if OS filesize is not equal to BMP internal filesize.
; ----------------------------------------------------------------------------------------------------------------------------------------------------
; BMP_InfoHeaderSize = BinaryPeek4(hdlBB ,0)
; BMP_Width        = BinaryPeek4(hdlBB , 4) ; Specifies the width of the bitmap, in pixels.
; BMP_Height       = BinaryPeek4(hdlBB , 8) ; Specifies the heigt of the bitmap, in pixels.
; BMP_Planes       = BinaryPeek2(hdlBB ,12) ; Specifies the number of planes for the target device. This member must be set to 1.
; BMP_BPP          = BinaryPeek2(hdlBB ,14) ; Bit per pixel. This value must be 1,4, 8, or 24.
; BMP_Compression  = BinaryPeek4(hdlBB ,16) ; Compression specifications.
;                                             values: 0=none, 1=RLE 8-bit per pixel, 2=RLE 4-bit per pixel, 3=Bitfields
; BMP_SizeImage    = BinaryPeek4(hdlBB ,20) ; Size of the bitmap data in bytes. This number must be rounded to the next 4 byte boundary.
; BMP_XPixPerMeter = BinaryPeek4(hdlBB ,24) ; Horizontal resolution expressed in pixel per meter, used by the target device.
; BMP_YPixPerMeter = BinaryPeek4(hdlBB ,28) ; Vertical resolution expressed in pixels per meter, used by the target device.
; BMP_ClrUsed      = BinaryPeek4(hdlBB ,32) ; Number of colors used by this bitmap. For a 8-bit per pixel bitmap this is 256.
;                                             If this value is zero, the bitmap uses the maximum number of colors corresponding
;                                             to the value of the BPP member.
; BMP_ClrImportant = BinaryPeek4(hdlBB ,36) ; Number of important colors. This number will be equal to the number of colors
;                                             when every color is important. If this value is zero, all colors are important.
;..........................................................................................................................................
; Detlev Dalitz.20020709.20100306.
;..........................................................................................................................................
#EndFunction
;------------------------------------------------------------------------------------------------------------------------------------------


; Test.

strMsgTitle = "Demo  udfBMPInfo (strFileBMP)"

AFN_Folder = DirWindows (0)

While @TRUE

   AFN_Title = strMsgTitle : " - choose a filename -"
   AFN_Directory = AFN_folder
   AFN_Filetypes = "BMP Files|*.bmp|All Files|*.*"
   AFN_Filename = "*.bmp"
   AFN_Flag = 1
   strFileBMP = AskFilename (AFN_Title, AFN_Directory, AFN_Filetypes, AFN_Filename, AFN_Flag)
   AFN_Folder = FilePath (strFileBMP)

   strMsgText = ""
   strMsgText = strMsgText : strFileBMP : @CRLF : @CRLF

   strInfoList = udfBMPInfo (strFileBMP)

   strInfoItem = ItemExtract (1, strInfoList, @TAB)

   Switch @TRUE
   Case strInfoItem == -1
      strMsgText = strMsgText : "Error. Input file does not exist."
      Break
   Case strInfoItem == -2
      strMsgText = strMsgText : "Error. Input file is not of type BMP."
      Break
   Case strInfoItem == -3
      strMsgText = strMsgText : "Error. Input file seems to be corrupted."
      Break
   Case strInfoItem > -1
      intBMP_Width = ItemExtract (1, strInfoList, @TAB)
      intBMP_Height = ItemExtract (2, strInfoList, @TAB)
      intBMP_Planes = ItemExtract (3, strInfoList, @TAB)
      intBMP_BPP = ItemExtract (4, strInfoList, @TAB)
      intBMP_Compression = ItemExtract (5, strInfoList, @TAB)
      intBMP_SizeImage = ItemExtract (6, strInfoList, @TAB)
      intBMP_XPixPerMeter = ItemExtract (7, strInfoList, @TAB)
      intBMP_YPixPerMeter = ItemExtract (8, strInfoList, @TAB)
      intBMP_ClrUsed = ItemExtract (9, strInfoList, @TAB)
      intBMP_ClrImportant = ItemExtract (10, strInfoList, @TAB)

      strMsgText = strFileBMP : @LF : @LF
      strMsgText = strMsgText : @LF : "Width       " : @TAB : " = " : @TAB : intBMP_Width
      strMsgText = strMsgText : @LF : "Height      " : @TAB : " = " : @TAB : intBMP_Height
      strMsgText = strMsgText : @LF : "Planes      " : @TAB : " = " : @TAB : intBMP_Planes
      strMsgText = strMsgText : @LF : "BPP         " : @TAB : " = " : @TAB : intBMP_BPP
      strMsgText = strMsgText : @LF : "Compression " : @TAB : " = " : @TAB : intBMP_Compression
      strMsgText = strMsgText : @LF : "SizeImage   " : @TAB : " = " : @TAB : intBMP_SizeImage
      strMsgText = strMsgText : @LF : "XPixPerMeter" : @TAB : " = " : @TAB : intBMP_XPixPerMeter
      strMsgText = strMsgText : @LF : "YPixPerMeter" : @TAB : " = " : @TAB : intBMP_YPixPerMeter
      strMsgText = strMsgText : @LF : "ClrUsed     " : @TAB : " = " : @TAB : intBMP_ClrUsed
      strMsgText = strMsgText : @LF : "ClrImportant" : @TAB : " = " : @TAB : intBMP_ClrImportant
      Break
   EndSwitch

   Message (strMsgTitle, strMsgText)

EndWhile

:CANCEL
Exit