OutFile CreateBitmap.exe !include "StrFunc.nsh" ${StrTok} Function CreateBitmap # Prepare function Exch $R3 Exch Exch $R2 Exch Exch 2 Exch $R1 Exch 2 Exch 3 Exch $R0 Exch 3 Push $R5 Push $R6 Push $R7 Push $R8 Push $R9 # Open requested file (just to write) FileOpen $R0 '$R0' w # Write the default structure for 24bit bitmaps FileWrite $R0 "BM" ;Required Startup FileWriteByte $R0 "0" ;File Size (Not important) FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "0" ;Reserved FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "54" ;Header Size (24 bits = 54) FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "40" ;Length of the Bitmap Info Header (24 bits = 40) FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "0" # Width (User Input) IntCmp $R1 0 0 0 +3 SetErrors Goto End # Distribute width Push $R1 StrCpy $R4 "" StrCpy $R5 "" StrCpy $R6 "" IntCmpU $R1 16777215 0 +3 # Size level 4 - Gigantic IntOp $R6 $R1 / 16777215 IntOp $R1 $R1 % 16777215 IntCmpU $R1 65535 0 +3 # Size level 3 - Big IntOp $R5 $R1 / 65535 IntOp $R1 $R1 % 65535 IntCmpU $R1 255 0 +3 # Size level 2 - Medium IntOp $R4 $R1 / 255 IntOp $R1 $R1 % 255 # R1 = Rest # Size level 1 - Small # Write width FileWriteByte $R0 "$R1" ;Width (User Input) FileWriteByte $R0 "$R4" FileWriteByte $R0 "$R5" FileWriteByte $R0 "$R6" Pop $R1 # Height (User Input) IntCmp $R2 0 0 0 +3 SetErrors Goto End Push $R2 # Distribute height StrCpy $R4 "" StrCpy $R5 "" StrCpy $R6 "" IntCmpU $R2 16777215 0 +3 # Size level 4 - Gigantic IntOp $R6 $R2 / 16777215 IntOp $R2 $R2 % 16777215 IntCmpU $R2 65535 0 +3 # Size level 3 - Big IntOp $R5 $R2 / 65535 IntOp $R2 $R2 % 65535 IntCmpU $R1 255 0 +3 # Size level 2 - Medium IntOp $R4 $R2 / 255 IntOp $R2 $R2 % 255 # R1 = Rest # Size level 1 - Small # Write height FileWriteByte $R0 "$R2" ;Height (User Input) FileWriteByte $R0 "$R4" FileWriteByte $R0 "$R5" FileWriteByte $R0 "$R6" Pop $R2 # Clear variables used by this operation # Continue to write FileWriteByte $R0 "1" ;Planes (Bitmap = 1) FileWriteByte $R0 "0" FileWriteByte $R0 "24" ;Bits per Pixel (This code uses 24 bits only) FileWriteByte $R0 "0" FileWriteByte $R0 "0" ;Compression (No Compression -> Bitmap = 0) FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "0" ;Bitmap Data Size (Not Important) FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "3" ;Hresolution (Not Important) FileWriteByte $R0 "1" FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "3" ;Vresolution (Not Important) FileWriteByte $R0 "1" FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "0" ;Number of Colors (24 bits = 0) FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "0" ;Number of Important Colors (24 bits = 0) FileWriteByte $R0 "0" FileWriteByte $R0 "0" FileWriteByte $R0 "0" # Initialize variables StrCpy $R6 0 StrCpy $R7 0 IntOp $R8 $R8 + 1 # Next Line NextLine: IntOp $R7 $R7 + 1 #Line Number StrCpy $R6 0 # Next Color of the Line NextColor: IntOp $R6 $R6 + 1 #Color Number of the Line /* Just a note how to create bitmaps: The bitmap is read from the end to the start, this code adapts to write inversely.*/ IntOp $R8 $R2 - $R7 IntOp $R8 $R8 * $R1 IntOp $R8 $R8 + $R6 #Total Number of Colors /* End of inverse code */ ${StrTok} $R4 $R3 | $R8 0 # Empty strings are converted to black. StrCmp $R4 "" 0 +2 StrCpy $R4 "000000" # Convert from hexadecimal to decimal and write from blue to red StrCpy $R5 $R4 "" 4 IntFmt $R5 "%d" 0x$R5 FileWriteByte $R0 $R5 ;Color Blue StrCpy $R5 $R4 "" 2 StrCpy $R5 $R5 2 IntFmt $R5 "%d" 0x$R5 FileWriteByte $R0 $R5 ;Color Green StrCpy $R5 $R4 2 IntFmt $R5 "%d" 0x$R5 FileWriteByte $R0 $R5 ;Color Red StrCmp $R6 $R1 EndingLine NextColor EndingLine: /* Just a note how to create bitmaps: Each line has to be divisible by 4, so add null characters.*/ IntOp $R9 $R1 * 3 IntOp $R9 $R9 % 4 IntOp $R9 4 - $R9 IntCmp $R9 0 +4 +4 FileWriteByte $R0 "0" IntOp $R9 $R9 - 1 Goto -3 /* End of extra null characters code */ StrCmp $R7 $R2 0 NextLine # End of bitmap creation End: FileClose $R0 # Return variables to user Pop $R9 Pop $R8 Pop $R7 Pop $R6 Pop $R5 Pop $R0 Pop $R4 Pop $R3 Pop $R2 Pop $R1 FunctionEnd Section Push "CreateBitmapExample.bmp" # Bitmap name (don't need to be an existant one) Push "6" # Width Push "3" # Height Push "|330000|660000|990000|CC0000|FF0000 \ ||003300|006600|009900|00CC00|00FF00 \ ||000033|000066|000099|0000CC|0000FF" # Colors in the format RRGGBB separated by vertical bars "|". # Any color that is lacking on the input will be converted to a black pixel. # "||" is the same as "|000000|". # Is possible to put the input on several lines as you see above, # but a restriction is to have a vertical bar "|" before the first # color after the second, third... lines. Call CreateBitmap ExecShell open "CreateBitmapExample.bmp" SectionEnd