Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/angle
Path: blob/main_old/scripts/bmp_to_nv12.py
1693 views
1
#!/usr/bin/python2
2
#
3
# Copyright 2016 The ANGLE Project Authors. All rights reserved.
4
# Use of this source code is governed by a BSD-style license that can be
5
# found in the LICENSE file.
6
#
7
# bmp_to_nv12.py:
8
# Script to convert a simple BMP file to an NV12 format. Used to create
9
# test images for the NV12 texture stream end to end tests
10
11
import sys
12
import struct
13
14
if len(sys.argv) != 4:
15
print("Usage: bmp_to_nv12.py input output prefix")
16
exit(0)
17
18
bmp_file = open(sys.argv[1], "rb")
19
20
magic = bmp_file.read(2)
21
if (magic != "BM"):
22
print("Invalid BMP magic")
23
exit(1)
24
25
file_size, = struct.unpack("I", bmp_file.read(4))
26
27
# eat reserved bytes
28
bmp_file.read(4)
29
30
offset, = struct.unpack("I", bmp_file.read(4))
31
32
headersize, = struct.unpack("I", bmp_file.read(4))
33
width, = struct.unpack("i", bmp_file.read(4))
34
height, = struct.unpack("i", bmp_file.read(4))
35
planes, = struct.unpack("H", bmp_file.read(2))
36
bpp, = struct.unpack("H", bmp_file.read(2))
37
compression, = struct.unpack("i", bmp_file.read(4))
38
image_size, = struct.unpack("i", bmp_file.read(4))
39
40
if (bpp != 24 or compression != 0):
41
print("Unsupported BMP file")
42
bmp_file.close()
43
exit(1)
44
45
bmp_file.seek(offset, 0)
46
pixels = bmp_file.read(width * height * 3)
47
bmp_file.close()
48
49
# convert to YUV 4:4:4
50
converted_pixels = bytearray(pixels)
51
for i in range(0, width * height):
52
R, = struct.unpack("B", pixels[i * 3 + 2])
53
G, = struct.unpack("B", pixels[i * 3 + 1])
54
B, = struct.unpack("B", pixels[i * 3])
55
converted_pixels[i * 3] = ((66 * R + 129 * G + 25 * B + 128) >> 8) + 16
56
converted_pixels[i * 3 + 1] = ((-38 * R - 74 * G + 112 * B + 128) >> 8) + 128
57
converted_pixels[i * 3 + 2] = ((112 * R - 94 * G - 18 * B + 128) >> 8) + 128
58
59
# downsample to packed UV buffer
60
uv_buffer = bytearray(width * height / 2)
61
for i in range(0, width * height / 2, 2):
62
U1 = converted_pixels[((((i / width) * 2) * width) + (i % width)) * 3 + 1]
63
U2 = converted_pixels[((((i / width) * 2) * width) + width + (i % width)) * 3 + 1]
64
V1 = converted_pixels[((((i / width) * 2) * width) + (i % width)) * 3 + 2]
65
V2 = converted_pixels[((((i / width) * 2) * width) + width + (i % width)) * 3 + 2]
66
uv_buffer[i] = (U1 + U2) / 2
67
uv_buffer[i + 1] = (V1 + V2) / 2
68
69
# extract the Y buffer
70
y_buffer = bytearray(width * height)
71
for i in range(0, width * height):
72
y_buffer[i] = converted_pixels[i * 3]
73
74
# write out the file as a C header
75
nv12_file = open(sys.argv[2], "w")
76
nv12_file.write("// Automatically generated from " + sys.argv[1] + "\n")
77
nv12_file.write("static const size_t " + sys.argv[3] + "_width = " + str(width) + ";\n")
78
nv12_file.write("static const size_t " + sys.argv[3] + "_height = " + str(height) + ";\n")
79
nv12_file.write("static const unsigned char " + sys.argv[3] + "_data[] = \n{")
80
for i in range(0, width * height):
81
if (i % 16) == 0:
82
nv12_file.write("\n ")
83
nv12_file.write(str(y_buffer[i]) + ",")
84
for i in range(0, width * height / 2):
85
if (i % 16) == 0:
86
nv12_file.write("\n ")
87
nv12_file.write(str(uv_buffer[i]) + ",")
88
nv12_file.write("\n};")
89
nv12_file.close()
90
91