Display .BMP files in RGB colors - WIN 10 ONLY

Discussion forum for all Windows batch related topics.

Moderator: DosItHelp

Post Reply
Message
Author
aGerman
Expert
Posts: 4043
Joined: 22 Jan 2010 18:01
Location: Germany

Display .BMP files in RGB colors - WIN 10 ONLY

#1 Post by aGerman » 05 Dec 2020 06:56

Recently I read across the specification of the BMP file format and I found it simple enough for processing in a Batch code. We already have a thread about how to process PPM files: viewtopic.php?f=3&t=8087&p=53745#p53745 The structure of uncompressed bitmaps with 24 bits color depth (and this is what the following code is for) is quite similar. It's a proof of concept which certainly has room for improvements. So, everyone is free to publish their updates here. For me this is just for fun. I don't have any use for it and I'll leave it alone ...

How does it work?
BMP files are binary files. Since we can't process binary data in Batch directly, I create a HEX dump using CERTUTIL. The file content begins with two data structures, BITMAPFILEHEADER and BITMAPINFOHEADER (links to their spec can be found in the code comments). This data contains values to verify that we got the right file format. And it contains values like the image size and the offset to the pixel data in the file that are necessary for the conversion we have to perform.
The way the pixels are saved makes the processing quite slow though. For the ANSI sequences we need the colors in RGB order, and we need the pixel rows top-down. However in the pixel array of the bitmap colors are in BGR order (which is the easy task), and the pixel rows are buttom-up. The latter means that the first 3 bytes we read in the pixel array belong to the bottom left pixel of the image, which requires an expensive reordering using temporary files.

To avoid this time-consuming conversion all the time new, I decided to create an intermediate .ansi file. It contains the ANSI sequences for the whole image. The TYPE command is now sufficient to print the image into the window. Only the internal color rendition is the task leftover for the console host to be performed.
The ANSI sequences I used seem to be unnecessarily long, but that's for a reason. I could have used the full block character along with the foreground color only. But depending on the font size, block characters may not fill the whole character cell and we may still see some spacing around it. I could have used a space character along with the background color only. This would look reasonable but it doesn't survive resizing of the window. Eventually I had to set both foreground and background to the same color, and to use any non-whitespace character to write the pixel (I have randomly chosen to use #).

The code doesn't resize the picture. Keep in mind that the pixels are represented by filling an entire character cell each. However, a temporary registry key is created (and removed afterwards) to change font and font size in order to get reasonable results.

Steffen

Code: Select all

@echo off &setlocal

rem Name of the bitmap file without extension
set "filename=123"
rem Window title necessary to identify it for the updated registry values
set "title=BMP Test"

if "%~1"=="" (
  rem If the .ansi file was not yet created, we will call :make_ansi to convert the .bmp content
  if not exist "%filename%.ansi" call :make_ansi || (pause&goto :eof)
  rem Update the size of the character cells which represent the pixels of the image
  >nul reg add "HKCU\Console\%title:\=_%" /f /v "FaceName"   /t REG_SZ    /d "Terminal"
  >nul reg add "HKCU\Console\%title:\=_%" /f /v "FontFamily" /t REG_DWORD /d 0x00000030
  >nul reg add "HKCU\Console\%title:\=_%" /f /v "FontSize"   /t REG_DWORD /d 0x00040006
  rem Restart the script to get the new settings applied
  start "%title%" /max "%comspec%" /c "%~fs0" #
  goto :eof
) else >nul reg delete "HKCU\Console\%title:\=_%" /f

rem Print the image
type "%filename%.ansi"
pause
goto :eof


rem Subroutine to convert the pixel array of the bitmap file into a file containing "true color" ANSI escape sequences
:make_ansi
setlocal EnableDelayedExpansion
set "outfile=!filename!.ansi"
2>nul del "!outfile!.raw.hex"

rem Batch isn't able to work with the binary data of a BMP file. Thus, we use certutil to create a HEX dump.
>nul certutil -encodehex "!filename!.bmp" "!outfile!.raw.hex" 4||(echo Unable to dump the bitmap&goto err)

rem rn is CR + LF
set "rn="&for /f "skip=1" %%i in ('echo(^|replace ? . /u /w') do if not defined rn (set rn=%%i^
%= don't alter =%
)

rem Certutil wrote 16 space-separated byte values per line. This is inconvenient because we have to reassemble them into sequences of 2, 4, or 3 bytes later on.
rem This will get easier if we write every value into a separate line first.
>"!outfile!.separate.hex" (for /f "usebackq tokens=1-16" %%a in ("!outfile!.raw.hex") do echo %%a!rn!%%b!rn!%%c!rn!%%d!rn!%%e!rn!%%f!rn!%%g!rn!%%h!rn!%%i!rn!%%j!rn!%%k!rn!%%l!rn!%%m!rn!%%n!rn!%%o!rn!%%p)
del "!outfile!.raw.hex"

rem Control Sequence Introducer
for /f %%e in ('echo prompt $E^|cmd') do set "csi=%%e["

rem We use SET /P to read one byte value at once. Sequences that represent numeric values are in little endian byte order.
rem For the variable naming refer to the structure documentations linked in the remarks.
<"!outfile!.separate.hex" (
  rem BITMAPFILEHEADER https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapfileheader
  set /p "bfType_1="&set /p "bfType_2="
  if "!bfType_1!!bfType_2!" neq "424d" (echo Wrong file type. Magic number must be 424d (ASCII "BM"^)&goto err)

  set /p "b4="&set /p "b3="&set /p "b2="&set /p "b1="
  set /a "bfSize=0x!b1!!b2!!b3!!b4!"
  for %%i in ("!filename!.bmp") do if !bfSize! neq %%~zi (echo File size doesn't match (!bfSize! vs. %%~zi^)&goto err)

  set /p "="&set /p "="&set /p "="&set /p "=" &rem bfReserved1 and bfReserved2 with two unused bytes each

  set /p "b4="&set /p "b3="&set /p "b2="&set /p "b1="
  set /a "bfOffBits=0x!b1!!b2!!b3!!b4!" &rem Offset in bytes between the beginning of the file and the pixel array

  rem BITMAPINFOHEADER https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader
  set /p "b4="&set /p "b3="&set /p "b2="&set /p "b1="
  set /a "biSize=0x!b1!!b2!!b3!!b4!"
  if !biSize! neq 40 (echo Wrong DIB header&goto err)

  set /p "b4="&set /p "b3="&set /p "b2="&set /p "b1="
  set /a "biWidth=0x!b1!!b2!!b3!!b4!" &rem Width of the bitmap in pixels

  set /p "b4="&set /p "b3="&set /p "b2="&set /p "b1="
  set /a "biHeight=0x!b1!!b2!!b3!!b4!" &rem Height of the bitmap in pixels

  set /a "chk=((biWidth>>31)&1)+((biHeight>>31)&1)"
  if !chk! neq 0 (echo Negative image size not supported&goto err)

  set /p "b2="&set /p "b1="
  set /a "biPlanes=0x!b1!!b2!"
  if !biPlanes! neq 1 (echo Number of planes must be 1&goto err)

  set /p "b2="&set /p "b1="
  set /a "biBitCount=0x!b1!!b2!"
  if !biBitCount! neq 24 (echo Only 24 bits color depth supported&goto err)

  set /p "b4="&set /p "b3="&set /p "b2="&set /p "b1="
  set /a "biCompression=0x!b1!!b2!!b3!!b4!"
  if !biCompression! neq 0 (echo Only uncompressed bitmaps supported&goto err)

  set /a "skip=bfOffBits-34" &rem We already read 34 bytes. Some further bytes are not of interest. We ignore them to get to the begin of the pixel array.
  for /l %%i in (1 1 !skip!) do set /p "="
  
  set /a "pad=(biWidth*3)%%4" &rem The pixel rows might be padded because the number of bytes has to be a multiple of 4
  if !pad! neq 0 set /a "pad=4-pad"

  rem A pixel consists of 3 bytes which represent the color in BGR order.
  rem The first 3 bytes belong to the lower left corner of the image. This means the order of the pixel array is bottom-up.
  rem Since we need both the colors in RGB order and the upper left corner first, we have to reorder literally everything.
  rem After these nested loops we got a file containing the "true color" ANSI sequences.
  echo The BMP file will be converted for you. This may take a while ...
  >"!outfile!" type nul
  for /l %%Y in (1 1 !biHeight!) do (
    >"!outfile!.~tmp" (
      set "row="
      for /l %%X in (1 1 !biWidth!) do (
        set /p "b="&set /p "g="&set /p "r="
        set /a "r=0x!r!,g=0x!g!,b=0x!b!"
        set "row=!row!%csi%38;2;!r!;!g!;!b!m%csi%48;2;!r!;!g!;!b!m#"
      )
      echo !row!%csi%0m
    )
    for /l %%i in (1 1 !pad!) do set /p "="
    >nul copy /b "!outfile!.~tmp" + "!outfile!"
    >nul move /y "!outfile!.~tmp" "!outfile!"
  )
)
2>nul del "!outfile!.separate.hex"
endlocal&exit /b 0
:err
2>nul del "!outfile!.separate.hex"
endlocal&exit /b 1

Code and bitmap file:
prntbmp.zip
(54.67 KiB) Downloaded 33 times
Attachments
Screenshot.jpg
Screenshot.jpg (72.38 KiB) Viewed 838 times
Last edited by aGerman on 05 Dec 2020 12:16, edited 1 time in total.
Reason: DWORD alignment in pixel rows

T3RRY
Posts: 117
Joined: 06 May 2020 10:14

Re: Display .BMP files in RGB colors - WIN 10 ONLY

#2 Post by T3RRY » 06 Dec 2020 05:19

aGerman wrote:
05 Dec 2020 06:56
Recently I read across the specification of the BMP file format and I found it simple enough for processing in a Batch code. We already have a thread about how to process PPM files: viewtopic.php?f=3&t=8087&p=53745#p53745 The structure of uncompressed bitmaps with 24 bits color depth (and this is what the following code is for) is quite similar. It's a proof of concept which certainly has room for improvements. So, everyone is free to publish their updates here. For me this is just for fun. I don't have any use for it and I'll leave it alone ...
It's a wonderful tool you've created there. Might be the peice of inspiration I need to pick up where I left of with a batch RPG adventure. I was previously converting images to ascii and manually adding in vt codes to color cells; however it was such a tedious process I lost the will to continue with it. With this I can jost convert them to directly to a file for typing - Absolutely lovely, Thankyou.

IcarusLives
Posts: 123
Joined: 17 Jan 2016 23:55

Re: Display .BMP files in RGB colors - WIN 10 ONLY

#3 Post by IcarusLives » 11 Dec 2020 20:58

Stunning work! This is beautiful. Thank you for mentioning my thread as well! I will be inspecting your code shortly.

aGerman
Expert
Posts: 4043
Joined: 22 Jan 2010 18:01
Location: Germany

Re: Display .BMP files in RGB colors - WIN 10 ONLY

#4 Post by aGerman » 12 Dec 2020 05:04

Thank you guys :)
It's also possible to "reverse-engineer" the HEX dump of a bitmap out of another data source in order to create a bitmap file. How to do that depends on the format of the source.
I think for testing HEX strings in RRGGBB order should be both common and straightforward.

smiley.txt

Code: Select all

; smiley face, 17 x 17 pixels represented in HEX format RRGGBB
FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF
FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF 454545 454545 454545 454545 454545 FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF
FFFFFF FFFFFF FFFFFF FFFFFF 454545 454545 FFFFEB FFFFC7 FFFE93 FFFE93 FFCE00 454545 454545 FFFFFF FFFFFF FFFFFF FFFFFF
FFFFFF FFFFFF FFFFFF 454545 FFFFEB FFFFC7 FFFD13 FFFD13 FFEA00 FFEA00 FFEA00 FFCE00 FE9D00 454545 FFFFFF FFFFFF FFFFFF
FFFFFF FFFFFF 454545 FFFFC7 FFFE93 000000 000000 FFEA00 FFEA00 FFEA00 000000 000000 FFCE00 FE9D00 454545 FFFFFF FFFFFF
FFFFFF FFFFFF 454545 FFFE93 FFFD13 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 FFCE00 454545 FFFFFF FFFFFF
FFFFFF 454545 FFFFC7 FFFD13 FFEA00 FFEA00 000000 FFEA00 FFEA00 FFEA00 000000 FFEA00 FFEA00 FFC900 FE9D00 454545 FFFFFF
FFFFFF 454545 FFFE93 FFFD13 FFEA00 FFEA00 000000 FFEA00 FFEA00 FFEA00 000000 FFEA00 FFEA00 FFC900 FFB400 454545 FFFFFF
FFFFFF 454545 FFFE93 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 FFC900 FFB400 454545 FFFFFF
FFFFFF 454545 FFFD13 FFEA00 333333 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 FFEA00 333333 FFC900 FFB400 454545 FFFFFF
FFFFFF 454545 FFCE00 FFEA00 000000 000000 000000 000000 000000 000000 000000 000000 000000 FFC900 FE9D00 454545 FFFFFF
FFFFFF FFFFFF 454545 FFCE00 FFEA00 000000 FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF 000000 FFC900 FFCE00 454545 FFFFFF FFFFFF
FFFFFF FFFFFF 454545 FFCE00 FFCE00 FFE500 000000 000000 000000 000000 000000 FFC900 FFCE00 FE9D00 454545 FFFFFF FFFFFF
FFFFFF FFFFFF FFFFFF 454545 FFCE00 FFCE00 FFC900 FFC900 FFC900 FFC900 FFC900 FFCE00 FE9D00 454545 FFFFFF FFFFFF FFFFFF
FFFFFF FFFFFF FFFFFF FFFFFF 454545 454545 FFB400 FFB400 FFB400 FFB400 FE9D00 454545 454545 FFFFFF FFFFFF FFFFFF FFFFFF
FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF 454545 454545 454545 454545 454545 FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF
FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF FFFFFF

makebmp.bat

Code: Select all

@echo off &setlocal
rem Name of the .txt file (without file extension) which contains the pixel information
rem The expected format is: lines of space-separated HEX strings in RRGGBB order
set "filename=smiley"

setlocal EnableDelayedExpansion
rem Create the pixel array first because we have to determine the dimensions anyway before the headers can be written
set /a "width=0,height=0,firstrow=1"
>"!filename!.hex" type nul
for /f "usebackq delims=" %%Y in ("!filename!.txt") do (
  set /a "height+=1"
  >"!filename!.hex.~tmp" (
    for %%X in (%%Y) do (
      if defined firstrow set /a "width+=1"
      set "value=%%X"
      rem 3 bytes per pixel in BB GG RR order
      echo !value:~-2! !value:~-4,2! !value:~-6,2!
    )
    if defined firstrow (
      set "firstrow="
      rem The pixel rows may require a padding of 1..3 bytes because the number of bytes must be a multiple of 4 (DWORD alignment), yields 0 if no padding necessary
      set /a "pad=3-(width*3-1)%%4"
    )
    rem Pad the pixel row (if necessary) to get it DWORD-aligned, the loop won't run if pad is 0
    for /l %%i in (1 1 !pad!) do echo 00
    echo(
  )
  rem The order of pixel rows must be bottom-up, prepend the new row to the existing data
  >nul copy /b "!filename!.hex.~tmp" + "!filename!.hex"
  >nul move /y "!filename!.hex.~tmp" "!filename!.hex"
)

rem 54 is the total size of the BITMAPFILEHEADER and BITMAPINFOHEADER at the beginning of the file, 3 is the number of bytes per pixel
set /a "filesize=54+(width*3+pad)*height"

rem Since we're about to write HEX-encoded data, convert integers to HEX strings
cmd /c exit !filesize!
set "filesize=!=exitcode!"
cmd /c exit !width!
set "width=!=exitcode!"
cmd /c exit !height!
set "height=!=exitcode!"

rem Finally we create the two header structures, and prepend them to the pixel array
rem Note that numbers consisting of multiple bytes have to be written in little endian byte order
>"!filename!.hex.~tmp" (
  rem BITMAPFILEHEADER https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapfileheader
  echo 42 4D &rem ASCII values of 'B' 'M'
  echo !filesize:~-2! !filesize:~4,2! !filesize:~2,2! !filesize:~0,2!
  echo 00 00 &rem Unused
  echo 00 00 &rem Unused
  echo 36 00 00 00 &rem Offset to the pixel array is 54 (14 bytes is the size of BITMAPFILEHEADER, 40 bytes is the size of BITMAPINFOHEADER)
  echo(
  rem BITMAPINFOHEADER https://docs.microsoft.com/en-us/windows/win32/api/wingdi/ns-wingdi-bitmapinfoheader
  echo 28 00 00 00 &rem 40 is the size of the BITMAPINFOHEADER
  echo !width:~-2! !width:~4,2! !width:~2,2! !width:~0,2!
  echo !height:~-2! !height:~4,2! !height:~2,2! !height:~0,2!
  echo 01 00 &rem One plane
  echo 18 00 &rem 24 bits per pixel
  echo 00 00 00 00 &rem 0 is for "uncompressed RGB bitmap"
  echo 00 00 00 00 &rem Size of the image which can be set to 0 for uncompressed bitmaps
  echo C4 0E 00 00 &rem Horizontal resolution in pixels per meter, set to 3780 (~96 dpi), might get ignored anyway
  echo C4 0E 00 00 &rem Vertical resolution in pixels per meter, set to 3780 (~96 dpi), might get ignored anyway
  echo 00 00 00 00 &rem Number of color indices in the color table (no color table present in a 24-bit bitmap because it's "true color" rather than "palette color")
  echo 00 00 00 00 &rem Number of color indices that are considered important for displaying the bitmap, 0 is for "every color is important", pointless here
  echo(
)
>nul copy /b "!filename!.hex.~tmp" + "!filename!.hex"
>nul move /y "!filename!.hex.~tmp" "!filename!.hex"
>nul certutil -decodehex -f "!filename!.hex" "!filename!.bmp" &rem Make the binary file out of the HEX data
:: del "!filename!.hex"
The result may look familiar => :)

I don't think this code is particularly useful. However, it may help to understand what I did in the first code.
I keep the .hex file (just uncomment the last line elsewise) because the content shows the structure of a bitmap file: First two blocks are the headers. Beginning with the 3rd block you'll find the pixel rows (last row first). Values are in BB GG RR order. The lone standing 00 byte is a padding because the number of bytes which represent a row must be a multiple of 4.
For the given example it looks like that:
smiley.hex

Code: Select all

42 4D 
AA 03 00 00
00 00 
00 00 
36 00 00 00 

28 00 00 00 
11 00 00 00
11 00 00 00
01 00 
18 00 
00 00 00 00 
00 00 00 00 
C4 0E 00 00 
C4 0E 00 00 
00 00 00 00 
00 00 00 00 

FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
00

FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
45 45 45
45 45 45
45 45 45
45 45 45
45 45 45
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
00

FF FF FF
FF FF FF
FF FF FF
FF FF FF
45 45 45
45 45 45
00 B4 FF
00 B4 FF
00 B4 FF
00 B4 FF
00 9D FE
45 45 45
45 45 45
FF FF FF
FF FF FF
FF FF FF
FF FF FF
00

FF FF FF
FF FF FF
FF FF FF
45 45 45
00 CE FF
00 CE FF
00 C9 FF
00 C9 FF
00 C9 FF
00 C9 FF
00 C9 FF
00 CE FF
00 9D FE
45 45 45
FF FF FF
FF FF FF
FF FF FF
00

FF FF FF
FF FF FF
45 45 45
00 CE FF
00 CE FF
00 E5 FF
00 00 00
00 00 00
00 00 00
00 00 00
00 00 00
00 C9 FF
00 CE FF
00 9D FE
45 45 45
FF FF FF
FF FF FF
00

FF FF FF
FF FF FF
45 45 45
00 CE FF
00 EA FF
00 00 00
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
00 00 00
00 C9 FF
00 CE FF
45 45 45
FF FF FF
FF FF FF
00

FF FF FF
45 45 45
00 CE FF
00 EA FF
00 00 00
00 00 00
00 00 00
00 00 00
00 00 00
00 00 00
00 00 00
00 00 00
00 00 00
00 C9 FF
00 9D FE
45 45 45
FF FF FF
00

FF FF FF
45 45 45
13 FD FF
00 EA FF
33 33 33
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
33 33 33
00 C9 FF
00 B4 FF
45 45 45
FF FF FF
00

FF FF FF
45 45 45
93 FE FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 C9 FF
00 B4 FF
45 45 45
FF FF FF
00

FF FF FF
45 45 45
93 FE FF
13 FD FF
00 EA FF
00 EA FF
00 00 00
00 EA FF
00 EA FF
00 EA FF
00 00 00
00 EA FF
00 EA FF
00 C9 FF
00 B4 FF
45 45 45
FF FF FF
00

FF FF FF
45 45 45
C7 FF FF
13 FD FF
00 EA FF
00 EA FF
00 00 00
00 EA FF
00 EA FF
00 EA FF
00 00 00
00 EA FF
00 EA FF
00 C9 FF
00 9D FE
45 45 45
FF FF FF
00

FF FF FF
FF FF FF
45 45 45
93 FE FF
13 FD FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 EA FF
00 CE FF
45 45 45
FF FF FF
FF FF FF
00

FF FF FF
FF FF FF
45 45 45
C7 FF FF
93 FE FF
00 00 00
00 00 00
00 EA FF
00 EA FF
00 EA FF
00 00 00
00 00 00
00 CE FF
00 9D FE
45 45 45
FF FF FF
FF FF FF
00

FF FF FF
FF FF FF
FF FF FF
45 45 45
EB FF FF
C7 FF FF
13 FD FF
13 FD FF
00 EA FF
00 EA FF
00 EA FF
00 CE FF
00 9D FE
45 45 45
FF FF FF
FF FF FF
FF FF FF
00

FF FF FF
FF FF FF
FF FF FF
FF FF FF
45 45 45
45 45 45
EB FF FF
C7 FF FF
93 FE FF
93 FE FF
00 CE FF
45 45 45
45 45 45
FF FF FF
FF FF FF
FF FF FF
FF FF FF
00

FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
45 45 45
45 45 45
45 45 45
45 45 45
45 45 45
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
00

FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
FF FF FF
00

Steffen

Post Reply