bmp2bitplane.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. import os
  2. import re
  3. import string
  4. import sys
  5. import binascii
  6. import math
  7. def openfile(filename):
  8. return open(filename)
  9. def mk_sint(s):
  10. a = ord(s[1])
  11. b = ord(s[0])
  12. return (a<<8) + b
  13. def mk_int(s):
  14. a = ord(s[3])
  15. b = ord(s[2])
  16. c = ord(s[1])
  17. d = ord(s[0])
  18. return (a<<32) + (b<<16) + (c<<8) + d
  19. def main():
  20. file = sys.argv[1]
  21. asmfile = string.replace(file,".bmp",".s")
  22. basename = string.replace(file,".bmp","")
  23. fp =openfile(file)
  24. header_offset = 14 + 40
  25. data = fp.read()
  26. fp.close()
  27. type = mk_sint(data[0:2])
  28. size = mk_int(data[2:6])
  29. width = mk_int(data[18:22])
  30. height = mk_int(data[22:26])
  31. bits_per_pixel = mk_int(data[28:32])
  32. num_of_colors = mk_int(data[46:50])
  33. bytes_per_line = width / 8
  34. bytes_per_line_padded = bytes_per_line + (4-(bytes_per_line % 4))
  35. header = data[0:header_offset]
  36. colors = data[header_offset: header_offset + (num_of_colors * 4)]
  37. data = data[header_offset + (num_of_colors * 4):]
  38. raw = []
  39. for i in data:
  40. raw.append(ord(i))
  41. raw_len = len(raw)
  42. print "file:\t\t%s" % file
  43. print "basename:\t%s" % asmfile
  44. print "header info"
  45. print "type: \t\t%04X " % type
  46. print "size: \t\t%i bytes" % size
  47. print "width: \t\t%i pixel" % width
  48. print "height: \t%i pixel" % height
  49. print "bit per pixel:\t%i" % bits_per_pixel
  50. print "num of colors:\t%i" % num_of_colors
  51. print "imagedata: \t%s bytes" % raw_len
  52. print "per line: \t%i bytes" % bytes_per_line
  53. print "per line pad: \t%i bytes" % bytes_per_line_padded
  54. bitplane={}
  55. for bit in range(0,bits_per_pixel):
  56. bitplane[bit] = []
  57. bytes = [0,0,0,0]
  58. bit_cnt =0
  59. cnt=0
  60. last_progress = 0
  61. for byte in raw:
  62. cnt+=1
  63. progress = cnt / (raw_len/100)
  64. if (progress%10)==0:
  65. if (progress>last_progress):
  66. print "converting bmp to bitplane buffers %i%% done" % (progress)
  67. last_progress = progress
  68. if bits_per_pixel == 4 :
  69. hi_nibble = (byte >> 4)
  70. lo_nibble = byte & 16
  71. hi_nibble_bin = ''
  72. for nibble in (hi_nibble,lo_nibble):
  73. for plane in range(bits_per_pixel-1,-1,-1):
  74. if (nibble & (1 << plane)):
  75. bytes[plane] |= 1 << bit_cnt
  76. bit_cnt += 1
  77. if (bit_cnt==8):
  78. for i in range(0,bits_per_pixel):
  79. bitplane[i].append(bytes[i])
  80. bytes=[0,0,0,0]
  81. bit_cnt =0
  82. if bits_per_pixel == 1 :
  83. bitplane[0] = raw
  84. break
  85. out='';
  86. for plane in range(0,bits_per_pixel):
  87. print "bitplane %i has %i bytes " % (plane,len(bitplane[plane]))
  88. x_tiles = width / 8
  89. y_tiles = height / 8
  90. cnt=0
  91. last_progress=0
  92. fp = open(asmfile,'w')
  93. tile_cnt = 0
  94. out ="\n\n\n%s:\n\n" % (basename)
  95. fp.write(out)
  96. #for yt in range(0,y_tiles):
  97. for yt in range(y_tiles-1,-1,-1): # needed for h flip
  98. out ="; ### row %02x ### \n" % yt
  99. fp.write(out)
  100. progress = cnt / (raw_len/100)
  101. if(progress%5)==0:
  102. print "building asm include %i%% done" % (progress)
  103. #last_progress = progress
  104. for xt in range(0,x_tiles):
  105. for plane in range(0,bits_per_pixel):
  106. out = ' .db '
  107. for y in range(((yt+1)*8)-1,(yt*8)-1,-1): # needed for h flip
  108. #for y in range(yt*8,(yt+1)*8):
  109. out += "$%02x," % bitplane[plane][(y*x_tiles)+xt]
  110. cnt+=1
  111. out = out[:-1]
  112. out += ' ; tile=%02x plane=%02x row=%02x col=%02x \n' % (tile_cnt,plane,yt,xt)
  113. fp.write(out)
  114. tile_cnt+=1
  115. fp.close()
  116. if __name__ == '__main__':
  117. if len(sys.argv) is 2:
  118. main()
  119. else:
  120. print "usage: %s in out" % sys.argv[0]