{{
import datetime
import malcat

def pval(key, val=None, fmt="{}", va=False, rva=False, kalign=30, valign=0, formated=False):
    r = "[normal]{}[/normal]:".format(key)
    lr = len(r) - 17
    if lr < kalign:
        r += (" "*(kalign-lr))
    if isinstance(val, malcat.StructAccess):
        if val.has_enum and val.enum:
            d = "[color6]{}[/color6]([dim]{}[/dim])".format(val.enum, fmt.format(val.value))
            formated = True
            ld = len(d) - len("[color3][/color3][dim][/dim]")
        else:
            d = fmt.format(val.value)
            ld = len(d)
        val = val.value
    else:
        d = fmt.format(val)
        ld = len(d)
    if not formated:
        if type(val) == int: 
            if val == 0:
                grp = "dim"
            elif rva:
                grp = "rva"
            elif va:
                grp = "va"
            else:
                grp = "normal"
        else:
            grp = "normal"
        d = "[{}]{}[/{}]".format(grp,d,grp)
    if ld < valign:
        d += (" "*(valign-ld))
    write(r+d)  

def bitfieldpp(fa):
    s = []
    for i in range(fa.count - 1, -1, -1):
        bit = fa.at(i)
        if bit.value:
            s.append("[color5]{}[/color5]([dim]{:X}[/dim])".format(bit.name, 1 << i))
    if s:
        return  " + ".join(s)
    else:
        return "[dim]0[/dim]"

def pbitfield(key, fa, kalign=30):    
    r = "[normal]{}[/normal]:".format(key)
    lr = len(r) - 17
    if lr < kalign:
        r += (" "*(kalign-lr))
    write(r + bitfieldpp(fa))

}}
[color1]BitmapInfoHeader[/color1]
  {{ pval("SizeOfheader", analysis.struct.BitmapInfoHeader.biSize, "{:d} bytes") }}
  {{ pval("Width", analysis.struct.BitmapInfoHeader.biWidth, "{:d} pixels", valign=24) }} {{ pval("Height", analysis.struct.BitmapInfoHeader.biHeight, "{:d} pixels") }}
  {{ pval("Bpp", analysis.struct.BitmapInfoHeader.biBitCount, "{:d}", valign=24) }} {{ pval("Planes", analysis.struct.BitmapInfoHeader.biPlanes, "{:d}") }}
{{ if analysis.struct["BitmapInfoHeader"]["biSize"] >= 40:}}

  {{ pval("Compression", analysis.struct.BitmapInfoHeader.biCompression) }}
  {{ pval("Size of image", analysis.struct.BitmapInfoHeader.biSizeImage) }}
  {{ pval("Xres", analysis.struct.BitmapInfoHeader.biXres, valign=24) }} {{ pval("Yres", analysis.struct.BitmapInfoHeader.biYres) }}
  {{ pval("Colors Used", analysis.struct.BitmapInfoHeader.biColorsUsed, valign=24) }} {{ pval("Colors important", analysis.struct.BitmapInfoHeader.biColorsImportant) }}
{{:end}}
{{ if "Palette" in analysis.struct.BitmapInfoHeader: }}

[color1]Palette[/color1]
  {{ for i in range(min(8, analysis.struct.BitmapInfoHeader.Palette.count)): write("{}rgb([color5]{}[/color5],[color5]{}[/color5],[color5]{}[/color5])".format(i > 0 and ", " or "", analysis.struct.BitmapInfoHeader.Palette[i]["Red"],analysis.struct.BitmapInfoHeader.Palette[i]["Green"],analysis.struct.BitmapInfoHeader.Palette[i]["Blue"])) }}{{if len(analysis.struct.BitmapInfoHeader.Palette) > 8:}}, ... {{:end}}
{{:end}}

[color1]Image[/color1]
  Data:                         [fa]{{write("{:08x}".format(analysis.struct.biImageData.offset))}}[/fa]-[fa]{{write("{:08x}".format(analysis.struct.biImageData.offset + analysis.struct.biImageData.size - 1))}}[/fa]  ([dim]{{ analysis.struct.biImageData.size}} bytes[/dim])
{{if "biAndMask" in analysis.struct:}}
  Mask:                         [fa]{{write("{:08x}".format(analysis.struct.biAndMask.offset))}}[/fa]-[fa]{{write("{:08x}".format(analysis.struct.biAndMask.offset + analysis.struct.biAndMask.size - 1))}}[/fa]  ([dim]{{ analysis.struct.biAndMask.size}} bytes[/dim])
{{:end}} 
