summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorShixiang Zheng <shixiang.zheng@rock-chips.com>2019-04-01 18:05:39 +0800
committerTao Huang <huangtao@rock-chips.com>2019-04-08 15:22:47 +0800
commitce0fe97e4ec61933956231f9808e6c969555569b (patch)
treeaf240ebcf390b4be23c4a54fb705f8425156c9af /scripts
parent86bc58f14158f6e572af0afcd6b215d1f2606c8b (diff)
scripts/bmpconvert: add bmpconvert for auto convert bmpfile
Change-Id: Ic1be83af4de8b586b83c3398e42368106a4fd7e2 Signed-off-by: Shixiang Zheng <shixiang.zheng@rock-chips.com>
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/bmpconvert328
1 files changed, 328 insertions, 0 deletions
diff --git a/scripts/bmpconvert b/scripts/bmpconvert
new file mode 100755
index 000000000000..8363429e929c
--- /dev/null
+++ b/scripts/bmpconvert
@@ -0,0 +1,328 @@
+#!/usr/bin/env python
+# SPDX-License-Identifier: GPL-2.0 */
+# -*- coding: utf-8 -*-
+
+from struct import unpack, pack
+import sys
+import getopt
+
+
+class BMPFile:
+
+ def __init__(self, file_path, force_revers=0, force_swap=0):
+ self.file = open(file_path, "rb+")
+ # bmp head 14bit
+ self.bfType = unpack("<h", self.file.read(2))[0]
+ self.bfSize = unpack("<i", self.file.read(4))[0]
+ self.bfReserved1 = unpack("<h", self.file.read(2))[0]
+ self.bfReserved2 = unpack("<h", self.file.read(2))[0]
+ self.bfOffBits = unpack("<i", self.file.read(4))[0]
+
+ self.biSize = unpack("<i", self.file.read(4))[0]
+ self.biWidth = unpack("<i", self.file.read(4))[0]
+ self.biHeight = unpack("<i", self.file.read(4))[0]
+ self.biPlanes = unpack("<h", self.file.read(2))[0]
+ self.biBitCount = unpack("<h", self.file.read(2))[0]
+ # bmp parameter 40 bit normaally
+ self.biCompression = unpack("<i", self.file.read(4))[0]
+ self.biSizeImage = unpack("<i", self.file.read(4))[0]
+ self.biXPixelsPerMeter = unpack("<i", self.file.read(4))[0]
+ self.biYPixelsPerMeter = unpack("<i", self.file.read(4))[0]
+ self.biClrUsed = unpack("<i", self.file.read(4))[0]
+ self.biClrImportant = unpack("<i", self.file.read(4))[0]
+ self.head = []
+ self.color_map = []
+ self.bmp_data = []
+ self.bf_map = []
+ self.force_revers = force_revers
+ self.force_swap = force_swap
+ # some software change parameter size more than 40 bit
+ if self.biSize > 40:
+ self.read_other(self.biSize-40)
+
+ if self.biBitCount == 8:
+ for i in range(256):
+ self.color_map.append(
+ [unpack("<B", self.file.read(1))[0], unpack("<B", self.file.read(1))[0],
+ unpack("<B", self.file.read(1))[0]])
+ self.file.read(1)
+ if self.biBitCount == 16 and self.biCompression == 3:
+ for i in range(4):
+ self.bf_map.append(
+ [unpack("<i", self.file.read(4))[0]]
+ )
+ if self.biBitCount == 24:
+ self.get_24bit_data()
+ elif self.biBitCount == 16:
+ if self.biCompression == 3:
+ self.bmp16bit_to_24bit_bf()
+ else:
+ self.bmp16bit_to_24bit()
+ elif self.biBitCount == 8:
+ if self.biCompression == 1:
+ # print("8bit rle file not convert")
+ self.file.close()
+ return
+ elif self.biCompression == 0:
+ self.bmp8bit_to_24bit()
+ else:
+ print("err! bit_count is 8 while bit_compressoion is wrong")
+ self.file.close()
+ return
+ else:
+ self.bmp32bit_to_24bit()
+ self.rb_swap = 0
+ if self.bfReserved1 != 8399 and self.biHeight > 0:
+ self.reverse_bmp_data()
+ print("reverse data at first time")
+ if self.bfReserved1 != 8399:
+ self.rb_swap = 1
+ print("swap bgr to rgb at first time")
+ if self.force_revers:
+ self.reverse_bmp_data()
+ print("reverse data by force")
+ if self.force_swap:
+ self.rb_swap = 1
+ print("swap rb by force'")
+
+ if self.bfReserved1 == 8399:
+ self.file.close()
+ return
+
+ self.write_24bit(self.rb_swap)
+ self.file.close()
+
+ def read_other(self, n):
+ for i in range(n):
+ self.file.read(1)
+
+ def reverse_bmp_data(self):
+ self.bmp_data.reverse()
+
+ @staticmethod
+ def get_16bit_bgr_bf(pixel):
+ red = (pixel[1] & 0xf8) << 0
+ green = ((pixel[1] & 0x07) << 5) | ((pixel[0] & 0xe0) >> 3)
+ blue = ((pixel[0] & 0x1f) << 3)
+ new_pixel = [blue, green, red]
+ return new_pixel
+
+ def bmp32bit_to_24bit(self):
+ for height in range(abs(self.biHeight)):
+ bmp_data_row = []
+ # bmp file 4 align
+ count = 0
+ for width in range(self.biWidth):
+ bmp_data_row.append(
+ [unpack("<B", self.file.read(1))[0], unpack("<B", self.file.read(1))[0], unpack("<B", self.file.read(1))[0]])
+ self.file.read(1)
+ count = count + 4
+ while count % 4 != 0:
+ self.file.read(1)
+ count = count + 1
+ self.bmp_data.append(bmp_data_row)
+
+ def bmp16bit_to_24bit_bf(self):
+ self.get_16bit_data()
+ temp_data = self.bmp_data
+ self.bmp_data = []
+ for height in range(abs(self.biHeight)):
+ bmp_data_row = []
+ for width in range(self.biWidth):
+ bmp_data_row.append(
+ self.get_16bit_bgr_bf(temp_data[height][width])
+ )
+ self.bmp_data.append(bmp_data_row)
+
+ def bmp8bit_to_24bit_rle(self):
+ bmp_data_row = []
+ data_x = []
+ t_count = 0
+ loop = 1
+ while loop:
+ data1 = unpack("<B", self.file.read(1))[0]
+ if data1 > 0:
+ data2 = unpack("<B", self.file.read(1))[0]
+ for n in range(data1):
+ bmp_data_row.append(self.color_map[data2])
+ if data1 == 0:
+ data2 = unpack("<B", self.file.read(1))[0]
+ if data2 > 2:
+ data_count = data2
+ data_temp = unpack("<B", self.file.read(1))[0]
+ data_x.append(data_temp)
+ while data_temp != 0:
+ data_temp = unpack("<B", self.file.read(1))[0]
+ data_x.append(data_temp)
+ for m in range(data_count):
+ bmp_data_row.append(self.color_map[data_x[m]])
+ if data2 == 2:
+ print("data2 == 2")
+ if data2 == 0:
+ t_count += 1
+ self.bmp_data.append(bmp_data_row)
+ bmp_data_row = []
+ if data2 == 1:
+ print("encode over!")
+ loop = 0
+
+ def bmp8bit_to_24bit(self):
+ for height in range(abs(self.biHeight)):
+ bmp_data_row = []
+ count = 0
+ for width in range(self.biWidth):
+ bmp_data_row.append(
+ self.color_map[unpack("<B", self.file.read(1))[0]])
+ count = count + 1
+ while count % 4 != 0:
+ self.file.read(1)
+ count = count + 1
+ self.bmp_data.append(bmp_data_row)
+
+ @staticmethod
+ def get_16bit_bgr(pixel):
+ red = (pixel[1] & 0x7c) << 1
+ green = ((pixel[1] & 0x03) << 6) | ((pixel[0] & 0xe0) >> 2)
+ blue = ((pixel[0] & 0x1f) << 3)
+ new_pixel = [blue, green, red]
+ return new_pixel
+
+ def bmp16bit_to_24bit(self):
+ self.get_16bit_data()
+ temp_data = self.bmp_data
+ self.bmp_data = []
+ for height in range(abs(self.biHeight)):
+ bmp_data_row = []
+ for width in range(self.biWidth):
+ bmp_data_row.append(
+ self.get_16bit_bgr(temp_data[height][width])
+ )
+ self.bmp_data.append(bmp_data_row)
+
+ def get_head(self):
+ self.file.seek(0, 0)
+ for i in range(54):
+ self.head.append(unpack("<B", self.file.read(1))[0])
+ return self.head
+
+ def get_16bit_data(self):
+ for height in range(abs(self.biHeight)):
+ bmp_data_row = []
+ count = 0
+ for width in range(self.biWidth):
+ bmp_data_row.append(
+ [unpack("<B", self.file.read(1))[0], unpack("<B", self.file.read(1))[0]])
+ count = count + 2
+ while count % 4 != 0:
+ self.file.read(1)
+ count = count + 1
+ self.bmp_data.append(bmp_data_row)
+
+ def get_24bit_data(self):
+ for height in range(abs(self.biHeight)):
+ bmp_data_row = []
+ count = 0
+ for width in range(self.biWidth):
+ bmp_data_row.append(
+ [unpack("<B", self.file.read(1))[0], unpack("<B", self.file.read(1))[0], unpack("<B", self.file.read(1))[0]])
+ count = count + 3
+ while count % 4 != 0:
+ self.file.read(1)
+ count = count + 1
+ self.bmp_data.append(bmp_data_row)
+
+ def write_24bit(self,rb_swap):
+ self.file.seek(0, 0)
+ self.write_head_24bit()
+ self.write_data_24bit(rb_swap)
+
+ def write_head(self):
+ self.file.write(pack("<h", self.bfType))
+ self.file.write(pack("<i", self.bfSize))
+ self.file.write(pack("<h", self.bfReserved1))
+ self.file.write(pack("<h", self.bfReserved2))
+ self.file.write(pack("<i", self.bfOffBits)) # bfOffBits
+ self.file.write(pack("<i", self.biSize)) # biSize
+ self.file.write(pack("<i", self.biWidth))
+
+ self.file.write(pack("<i", self.biHeight))
+ self.file.write(pack("<h", self.biPlanes))
+ self.file.write(pack("<h", self.biBitCount)) # biBitCount
+ self.file.write(pack("<i", self.biCompression)) # biCompression
+ self.file.write(pack("<i", self.biSizeImage)) # biSizeImage
+ self.file.write(pack("<i", self.biXPixelsPerMeter)) # biXPixelsPerMeter
+ self.file.write(pack("<i", self.biYPixelsPerMeter)) # biYPixelsPerMeter
+ self.file.write(pack("<i", self.biClrUsed)) # biClrUsed
+ self.file.write(pack("<i", self.biClrImportant)) # biClrImportant try to mark whether is reversed
+
+ def write_head_24bit(self):
+ temp_bi_width = self.biWidth * 3
+ while temp_bi_width % 4 != 0:
+ temp_bi_width = temp_bi_width + 1
+ new_bf_size = temp_bi_width * abs(self.biHeight) + 54
+ self.file.write(pack("<h", self.bfType))
+ self.file.write(pack("<i", new_bf_size))
+ self.file.write(pack("<h", 8399)) # a mark for uboot dealing
+ self.file.write(pack("<h", self.bfReserved2))
+ self.file.write(pack("<i", 54)) # bfOffBits
+ self.file.write(pack("<i", 40)) # biSize
+ self.file.write(pack("<i", self.biWidth))
+ # force height to positive for vop not support negative height
+ if self.biHeight < 0:
+ self.file.write(pack("<i", self.biHeight * -1))
+ else:
+ self.file.write(pack("<i", self.biHeight))
+ self.file.write(pack("<h", self.biPlanes))
+ self.file.write(pack("<h", 24)) # biBitCount
+ self.file.write(pack("<i", 0)) # biCompression
+ self.file.write(pack("<i", 0)) # biSizeImage
+ self.file.write(pack("<i", 0)) # biXPixelsPerMeter
+ self.file.write(pack("<i", 0)) # biYPixelsPerMeter
+ self.file.write(pack("<i", 0)) # biClrUsed
+ self.file.write(pack("<i", 0)) # biClrImportant try to mark whether is reversed
+
+ def write_data_24bit(self, rb_swap):
+ for hg in range(abs(self.biHeight)):
+ count = 0
+ for wd in range(self.biWidth):
+ if rb_swap:
+ self.file.write(pack("<B", self.bmp_data[hg][wd][2]))
+ self.file.write(pack("<B", self.bmp_data[hg][wd][1]))
+ self.file.write(pack("<B", self.bmp_data[hg][wd][0]))
+ else:
+ self.file.write(pack("<B", self.bmp_data[hg][wd][0]))
+ self.file.write(pack("<B", self.bmp_data[hg][wd][1]))
+ self.file.write(pack("<B", self.bmp_data[hg][wd][2]))
+ count = count + 3
+ while count % 4 != 0:
+ self.file.write(pack("<B", 0))
+ count = count + 1
+
+
+if __name__ == "__main__":
+
+ swap = 0
+ revers = 0
+ par = len(sys.argv[1:])
+ if par == 1:
+ bmp = BMPFile(sys.argv[1])
+ elif par == 0:
+ print("This program is trying to convert different format of bmpfile to a same format"
+ "to make vop can handle bmpfile easily")
+ print("try such cmd to make it work python bmpconvert xxx/xxx.bmp")
+ else:
+ try:
+ opts, args = getopt.getopt(sys.argv[2:], "hrs", ["help", "reverse", "swap"])
+ for opt, arg in opts:
+
+ if opt in ('-h','--help'):
+ print("add -r option will force program to reverse data")
+ print("add -s option will force program to swap data of rb")
+ if opt in ("-r", "--reverse"):
+ revers = 1
+ if opt in ("-s", "--swap"):
+ swap = 1
+ bmp = BMPFile(sys.argv[1], revers, swap)
+ except getopt.GetoptError:
+ sys.exit(1)
+