#!/usr/bin/env python3 import os import subprocess import sys if len(sys.argv) != 2: print("usage: gen-cta-vic.py ", 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))