edid-decode: improve GTF/CVT failure messages
[edid-decode.git] / parse-ls-ext-block.cpp
blob1b74baad56427a4a7e74d6f25d48521397258a7e
1 // SPDX-License-Identifier: MIT
2 /*
3 * Copyright 2019-2020 Cisco Systems, Inc. and/or its affiliates. All rights reserved.
5 * Author: Hans Verkuil <hverkuil-cisco@xs4all.nl>
6 */
8 #include "edid-decode.h"
10 static void parse_string(const char *name, const unsigned char *x)
12 if (!*x)
13 return;
14 printf(" %s: ", name);
15 hex_block("", x + 1, *x, true, *x);
18 void edid_state::parse_string_table(const unsigned char *x)
20 unsigned width = 1 << (x[0] & 7);
22 printf(" UTF Type: ");
23 switch (x[0] & 7) {
24 case 0: printf("UTF 8\n"); break;
25 case 1: printf("UTF 16BE\n"); break;
26 case 2: printf("UTF 32BE\n"); break;
27 default:
28 printf("Unknown (0x%02x)\n", x[0] & 7);
29 fail("Unknown UTF Type (0x%02x).\n", x[0] & 7);
30 break;
32 printf(" Country Code ID (ISO 3166-3): %u\n", ((x[1] & 0x3f) << 8) | x[2]);
34 if (x[3] || x[4]) {
35 char name[4];
37 name[0] = ((x[3] & 0x7c) >> 2) + '@';
38 name[1] = ((x[3] & 0x03) << 3) + ((x[4] & 0xe0) >> 5) + '@';
39 name[2] = (x[4] & 0x1f) + '@';
40 name[3] = 0;
41 if (name[0] == '@') name[0] = ' ';
42 if (name[1] == '@') name[1] = ' ';
43 if (name[2] == '@') name[2] = ' ';
44 printf(" Language ID: '%s'\n", name);
46 x += 5;
47 parse_string("Manufacturer Name", x);
48 if (x[0] % width)
49 fail("Incorrect Manufacturer Name length.\n");
50 x += x[0] + 1;
51 parse_string("Model Name", x);
52 if (x[0] % width)
53 fail("Incorrect Model Name length.\n");
54 x += x[0] + 1;
55 if (hide_serial_numbers)
56 printf(" Serial Number: ...\n");
57 else
58 parse_string("Serial Number", x);
59 if (x[0] % width)
60 fail("Incorrect Serial Number length.\n");
63 void edid_state::preparse_ls_ext_block(unsigned char *x)
65 unsigned char *orig = x;
67 if (!replace_unique_ids)
68 return;
70 x += 5;
72 while (x[0] && x + x[0] < orig + 127) {
73 unsigned width = 1 << (x[1] & 7);
74 unsigned char *s = x + 6;
76 x += x[0];
77 if (width > 4)
78 continue;
80 s += s[0] + 1;
81 s += s[0] + 1;
82 for (unsigned i = 1; i <= s[0]; i += width) {
83 unsigned idx = (i - 1) / width;
85 memset(s + i, 0, width - 1);
86 s[i + width - 1] = idx < 6 ? '1' + idx : ' ';
89 replace_checksum(orig, EDID_PAGE_SIZE);
92 void edid_state::parse_ls_ext_block(const unsigned char *x)
94 const unsigned char *orig = x;
96 printf(" Version: %u.%u\n Unicode Version: %u.%u.%u\n",
97 x[1], x[2], (x[3] >> 4), x[3] & 0x0f, x[4]);
98 x += 5;
100 while (x[0] && x + x[0] < orig + 127) {
101 parse_string_table(x + 1);
102 x += x[0];
104 unused_bytes = orig + 127 - x;
105 if (!memchk(x, unused_bytes)) {
106 data_block.clear();
107 fail("Non-zero values in unused space.\n");