File: gen-cta-vic.py

package info (click to toggle)
libdisplay-info 0.2.0-2~bpo12%2B1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-backports
  • size: 1,156 kB
  • sloc: ansic: 8,413; python: 294; sh: 131; makefile: 3
file content (143 lines) | stat: -rwxr-xr-x 4,491 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#!/usr/bin/env python3

import os
import subprocess
import sys

if len(sys.argv) != 2:
    print("usage: gen-cta-vic.py <CTA-861-H PDF>", file=sys.stderr)
    sys.exit(1)
in_path = sys.argv[1]
in_basename = os.path.basename(in_path)

tool_dir = os.path.dirname(os.path.realpath(__file__))
out_path = tool_dir + "/../cta-vic-table.c"

# Page numbers for CTA-861-H
pages = {
    "timing": (41, 43),
    "sync": (44, 46),
    "aspect_ratio": (55, 58),
}

def extract_pages(page_range):
    pages = []
    page = ""
    cmd = ["pdftotext", "-f", str(page_range[0]), "-l", str(page_range[1]), "-layout", in_path, "-"]
    for l in subprocess.check_output(cmd, text=True):
        if l.startswith("\f"):
            pages.append(page)
            page = l[1:]
        else:
            page += l
    return pages

def extract_table(page):
    lines = [l.strip() for l in page.splitlines()]
    rows = []
    for l in lines:
        fields = [field.strip() for field in l.split("  ") if field != ""]
        rows.append(fields)
    return rows

def parse_vic_list(s):
    return [int(vic.strip()) for vic in s.split(",")]

def parse_hactive(s):
    # Some hactive pixel values have a footnote marker
    if s == "14402" or s == "28802":
        s = s[:-1]
    return int(s)

def parse_interlaced(s):
    if s == "Prog":
        return "false"
    elif s == "Int":
        return "true"
    else:
        assert(False)

def parse_timing_table(page, format_table):
    assert("Table 1 - Video Format Timings — Detailed Timing Information" in page)

    for fields in extract_table(page):
        if len(fields) != 11 or fields[0] == "VIC":
            continue
        for vic in parse_vic_list(fields[0]):
            format_table[vic] = {
                "vic": vic,
                "h_active": parse_hactive(fields[1]),
                "v_active": int(fields[2]),
                "interlaced": parse_interlaced(fields[3]),
                "pixel_clock_hz": int(float(fields[10]) * 1000 * 1000),
            }

def parse_polarity(pol):
    if pol == "P":
        return "POSITIVE"
    elif pol == "N":
        return "NEGATIVE"
    else:
        assert(False)

def parse_sync_table(page, format_table):
    assert("Table 2 - Video Format Timings — Detailed Sync Information" in page)

    for fields in extract_table(page):
        if len(fields) < 12:
            continue
        for vic in parse_vic_list(fields[0]):
            fmt = format_table[vic]
            fmt["h_front"] = int(fields[2])
            fmt["h_sync"] = int(fields[3])
            fmt["h_back"] = int(fields[4])
            fmt["h_sync_polarity"] = "DI_CTA_VIDEO_FORMAT_SYNC_" + parse_polarity(fields[5])
            fmt["v_front"] = int(fields[6])
            fmt["v_sync"] = int(fields[7])
            fmt["v_back"] = int(fields[8])
            fmt["v_sync_polarity"] = "DI_CTA_VIDEO_FORMAT_SYNC_" + parse_polarity(fields[9])

def parse_aspect_ratio_table(page, format_table):
    assert("Table 3 - Video Formats — Video ID Code and Aspect Ratios" in page)

    for fields in extract_table(page):
        if len(fields) != 5:
            continue
        vic = int(fields[0])
        fmt = format_table[vic]
        pic_ar = fields[3]
        if pic_ar == "64:276":
            # 64:27 has a footnote
            pic_ar = pic_ar[:-1]
        fmt["picture_aspect_ratio"] = "DI_CTA_VIDEO_FORMAT_PICTURE_ASPECT_RATIO_" + pic_ar.replace(":", "_")

format_table = {}
for page in extract_pages(pages["timing"]):
    parse_timing_table(page, format_table)
for page in extract_pages(pages["sync"]):
    parse_sync_table(page, format_table)
for page in extract_pages(pages["aspect_ratio"]):
    parse_aspect_ratio_table(page, format_table)

max_vic = 0
for vic in format_table:
    if vic > max_vic:
        max_vic = vic

# Sanity check
for vic in format_table:
    fmt = format_table[vic]
    assert("h_sync" in fmt)
    assert("picture_aspect_ratio" in fmt)

with open(out_path, "w+") as f:
    f.write("/* DO NOT EDIT! This file has been generated by gen-cta-vic.py from {}. */\n\n".format(in_basename))
    f.write('#include "cta.h"\n\n')
    f.write("const struct di_cta_video_format _di_cta_video_formats[] = {\n")
    for vic in format_table:
        f.write("\t[{}] = {{\n".format(vic))
        for k, v in format_table[vic].items():
            f.write("\t\t.{} = {},\n".format(k, v))
        f.write("\t},\n")
    f.write("};\n\n")
    f.write("const size_t _di_cta_video_formats_len = {};\n".format(max_vic + 1))