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))
|