^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) #!/usr/bin/env python
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) # SPDX-License-Identifier: GPL-2.0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) # -*- coding: utf-8 -*-
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) from struct import unpack, pack
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) import sys
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) import getopt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) class BMPFile:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) def __init__(self, file_path, force_revers=0, force_swap=0):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) self.file = open(file_path, "rb+")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) # bmp head 14bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) self.bfType = unpack("<h", self.file.read(2))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) self.bfSize = unpack("<i", self.file.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) self.bfReserved1 = unpack("<h", self.file.read(2))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) self.bfReserved2 = unpack("<h", self.file.read(2))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) self.bfOffBits = unpack("<i", self.file.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) self.biSize = unpack("<i", self.file.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) self.biWidth = unpack("<i", self.file.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) self.biHeight = unpack("<i", self.file.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) self.biPlanes = unpack("<h", self.file.read(2))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) self.biBitCount = unpack("<h", self.file.read(2))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) # bmp parameter 40 bit normaally
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) self.biCompression = unpack("<i", self.file.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) self.biSizeImage = unpack("<i", self.file.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) self.biXPixelsPerMeter = unpack("<i", self.file.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) self.biYPixelsPerMeter = unpack("<i", self.file.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) self.biClrUsed = unpack("<i", self.file.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) self.biClrImportant = unpack("<i", self.file.read(4))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) self.head = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) self.color_map = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) self.bmp_data = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) self.bf_map = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) self.force_revers = force_revers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) self.force_swap = force_swap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) # some software change parameter size more than 40 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) if self.biSize > 40:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) self.read_other(self.biSize-40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if self.biBitCount == 16 and self.biCompression == 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) for i in range(4):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) self.bf_map.append(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) [unpack("<i", self.file.read(4))[0]]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) if self.biBitCount == 24:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) self.get_24bit_data()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) elif self.biBitCount == 16:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if self.biCompression == 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) self.bmp16bit_to_24bit_bf()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) self.bmp16bit_to_24bit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) elif self.biBitCount == 8:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) # Not convert 8bit bmp logo to 24 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) self.file.close()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) self.bmp32bit_to_24bit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) self.rb_swap = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) if self.bfReserved1 != 8399 and self.biHeight > 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) self.reverse_bmp_data()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) print("reverse data at first time")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) if self.force_revers:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) self.reverse_bmp_data()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) print("reverse data by force")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if self.force_swap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) self.rb_swap = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) print("swap rb by force'")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if self.bfReserved1 == 8399:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) self.file.close()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) self.write_24bit(self.rb_swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) self.file.close()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) def read_other(self, n):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) for i in range(n):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) self.file.read(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) def reverse_bmp_data(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) self.bmp_data.reverse()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) @staticmethod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) def get_16bit_bgr_bf(pixel):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) red = (pixel[1] & 0xf8) << 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) green = ((pixel[1] & 0x07) << 5) | ((pixel[0] & 0xe0) >> 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) blue = ((pixel[0] & 0x1f) << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) new_pixel = [blue, green, red]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return new_pixel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) def bmp32bit_to_24bit(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) for height in range(abs(self.biHeight)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) bmp_data_row = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) # bmp file 4 align
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) count = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) for width in range(self.biWidth):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) bmp_data_row.append(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) [unpack("<B", self.file.read(1))[0], unpack("<B", self.file.read(1))[0], unpack("<B", self.file.read(1))[0]])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) self.file.read(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) count = count + 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) while count % 4 != 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) self.file.read(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) count = count + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) self.bmp_data.append(bmp_data_row)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) def bmp16bit_to_24bit_bf(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) self.get_16bit_data()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) temp_data = self.bmp_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) self.bmp_data = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) for height in range(abs(self.biHeight)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) bmp_data_row = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) for width in range(self.biWidth):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) bmp_data_row.append(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) self.get_16bit_bgr_bf(temp_data[height][width])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) self.bmp_data.append(bmp_data_row)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) def bmp8bit_to_24bit_rle(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) bmp_data_row = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) data_x = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) t_count = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) loop = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) while loop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) data1 = unpack("<B", self.file.read(1))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if data1 > 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) data2 = unpack("<B", self.file.read(1))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) for n in range(data1):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) bmp_data_row.append(self.color_map[data2])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if data1 == 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) data2 = unpack("<B", self.file.read(1))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) if data2 > 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) data_count = data2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) data_temp = unpack("<B", self.file.read(1))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) data_x.append(data_temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) while data_temp != 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) data_temp = unpack("<B", self.file.read(1))[0]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) data_x.append(data_temp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) for m in range(data_count):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) bmp_data_row.append(self.color_map[data_x[m]])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) if data2 == 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) print("data2 == 2")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) if data2 == 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) t_count += 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) self.bmp_data.append(bmp_data_row)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) bmp_data_row = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) if data2 == 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) print("encode over!")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) loop = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) def bmp8bit_to_24bit(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) for height in range(abs(self.biHeight)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) bmp_data_row = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) count = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) for width in range(self.biWidth):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) bmp_data_row.append(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) self.color_map[unpack("<B", self.file.read(1))[0]])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) count = count + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) while count % 4 != 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) self.file.read(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) count = count + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) self.bmp_data.append(bmp_data_row)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) @staticmethod
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) def get_16bit_bgr(pixel):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) red = (pixel[1] & 0x7c) << 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) green = ((pixel[1] & 0x03) << 6) | ((pixel[0] & 0xe0) >> 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) blue = ((pixel[0] & 0x1f) << 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) new_pixel = [blue, green, red]
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return new_pixel
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) def bmp16bit_to_24bit(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) self.get_16bit_data()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) temp_data = self.bmp_data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) self.bmp_data = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) for height in range(abs(self.biHeight)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) bmp_data_row = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) for width in range(self.biWidth):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) bmp_data_row.append(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) self.get_16bit_bgr(temp_data[height][width])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) )
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) self.bmp_data.append(bmp_data_row)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) def get_head(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) self.file.seek(0, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) for i in range(54):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) self.head.append(unpack("<B", self.file.read(1))[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) return self.head
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) def get_16bit_data(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) for height in range(abs(self.biHeight)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) bmp_data_row = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) count = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) for width in range(self.biWidth):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) bmp_data_row.append(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) [unpack("<B", self.file.read(1))[0], unpack("<B", self.file.read(1))[0]])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) count = count + 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) while count % 4 != 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) self.file.read(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) count = count + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) self.bmp_data.append(bmp_data_row)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) def get_24bit_data(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) for height in range(abs(self.biHeight)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) bmp_data_row = []
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) count = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) for width in range(self.biWidth):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) bmp_data_row.append(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) [unpack("<B", self.file.read(1))[0], unpack("<B", self.file.read(1))[0], unpack("<B", self.file.read(1))[0]])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) count = count + 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) while count % 4 != 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) self.file.read(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) count = count + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) self.bmp_data.append(bmp_data_row)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) def write_24bit(self,rb_swap):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) self.file.seek(0, 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) self.write_head_24bit()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) self.write_data_24bit(rb_swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) def write_head(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) self.file.write(pack("<h", self.bfType))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) self.file.write(pack("<i", self.bfSize))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) self.file.write(pack("<h", self.bfReserved1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) self.file.write(pack("<h", self.bfReserved2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) self.file.write(pack("<i", self.bfOffBits)) # bfOffBits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) self.file.write(pack("<i", self.biSize)) # biSize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) self.file.write(pack("<i", self.biWidth))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) self.file.write(pack("<i", self.biHeight))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) self.file.write(pack("<h", self.biPlanes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) self.file.write(pack("<h", self.biBitCount)) # biBitCount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) self.file.write(pack("<i", self.biCompression)) # biCompression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) self.file.write(pack("<i", self.biSizeImage)) # biSizeImage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) self.file.write(pack("<i", self.biXPixelsPerMeter)) # biXPixelsPerMeter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) self.file.write(pack("<i", self.biYPixelsPerMeter)) # biYPixelsPerMeter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) self.file.write(pack("<i", self.biClrUsed)) # biClrUsed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) self.file.write(pack("<i", self.biClrImportant)) # biClrImportant try to mark whether is reversed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) def write_head_24bit(self):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) temp_bi_width = self.biWidth * 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) while temp_bi_width % 4 != 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) temp_bi_width = temp_bi_width + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) new_bf_size = temp_bi_width * abs(self.biHeight) + 54
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) self.file.write(pack("<h", self.bfType))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) self.file.write(pack("<i", new_bf_size))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) self.file.write(pack("<h", 8399)) # a mark for uboot dealing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) self.file.write(pack("<h", self.bfReserved2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) self.file.write(pack("<i", 54)) # bfOffBits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) self.file.write(pack("<i", 40)) # biSize
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) self.file.write(pack("<i", self.biWidth))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) # force height to negative let logo show normal in windows
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) # the uboot code can deal with negative height
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) if self.biHeight < 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) self.file.write(pack("<i", self.biHeight))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) self.file.write(pack("<i", self.biHeight * -1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) self.file.write(pack("<h", self.biPlanes))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) self.file.write(pack("<h", 24)) # biBitCount
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) self.file.write(pack("<i", 0)) # biCompression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) self.file.write(pack("<i", 0)) # biSizeImage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) self.file.write(pack("<i", 0)) # biXPixelsPerMeter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) self.file.write(pack("<i", 0)) # biYPixelsPerMeter
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) self.file.write(pack("<i", 0)) # biClrUsed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) self.file.write(pack("<i", 0)) # biClrImportant try to mark whether is reversed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) def write_data_24bit(self, rb_swap):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) for hg in range(abs(self.biHeight)):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) count = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) for wd in range(self.biWidth):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if rb_swap:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) self.file.write(pack("<B", self.bmp_data[hg][wd][2]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) self.file.write(pack("<B", self.bmp_data[hg][wd][1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) self.file.write(pack("<B", self.bmp_data[hg][wd][0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) self.file.write(pack("<B", self.bmp_data[hg][wd][0]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) self.file.write(pack("<B", self.bmp_data[hg][wd][1]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) self.file.write(pack("<B", self.bmp_data[hg][wd][2]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) count = count + 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) while count % 4 != 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) self.file.write(pack("<B", 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) count = count + 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) if __name__ == "__main__":
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) swap = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) revers = 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) par = len(sys.argv[1:])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) if par == 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) bmp = BMPFile(sys.argv[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) elif par == 0:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) print("This program is trying to convert different format of bmpfile to a same format"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) "to make vop can handle bmpfile easily")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) print("try such cmd to make it work python bmpconvert xxx/xxx.bmp")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) try:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) opts, args = getopt.getopt(sys.argv[2:], "hrs", ["help", "reverse", "swap"])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) for opt, arg in opts:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) if opt in ('-h','--help'):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) print("add -r option will force program to reverse data")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) print("add -s option will force program to swap data of rb")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if opt in ("-r", "--reverse"):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) revers = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) if opt in ("-s", "--swap"):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) swap = 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) bmp = BMPFile(sys.argv[1], revers, swap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) except getopt.GetoptError:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) sys.exit(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)