@@ -176,6 +176,7 @@ struct edid_state {
dispid.is_display = dispid.has_product_identification =
dispid.has_display_parameters = dispid.has_type_1_7 =
dispid.has_display_interface_features = false;
+ dispid.block_number = 0;
// Block Map block state
block_map.saw_block_1 = false;
@@ -283,6 +284,7 @@ struct edid_state {
bool has_display_interface_features;
vec_timings_ext preferred_timings;
unsigned native_width, native_height;
+ unsigned block_number;
// Keep track of the found CTA-861 Tag/Extended Tag pairs.
// The unsigned value is equal to: (tag << 8) | ext_tag
std::set<unsigned> found_tags;
@@ -393,6 +395,7 @@ struct edid_state {
void parse_displayid_type_10_timing(const unsigned char *x, unsigned sz,
bool is_cta = false);
void preparse_displayid_block(const unsigned char *x);
+ unsigned displayid_block(const unsigned version, const unsigned char *x, unsigned offset, unsigned length);
void parse_displayid_block(const unsigned char *x);
void parse_displayid_vesa(const unsigned char *x);
void parse_displayid_cta_data_block(const unsigned char *x);
@@ -1651,47 +1651,9 @@ void edid_state::preparse_displayid_block(const unsigned char *x)
}
}
-void edid_state::parse_displayid_block(const unsigned char *x)
+unsigned edid_state::displayid_block(const unsigned version, const unsigned char *x, unsigned offset, unsigned length)
{
- unsigned version = x[1];
- unsigned length = x[2];
- unsigned prod_type = x[3]; // future check: based on type, check for required data blocks
- unsigned ext_count = x[4];
unsigned i;
-
- printf(" Version: %u.%u\n Extension Count: %u\n",
- version >> 4, version & 0xf, ext_count);
-
- if (dispid.is_base_block) {
- dispid.version = version;
- printf(" %s: %s\n", product_type(prod_type, true).c_str(),
- product_type(prod_type, false).c_str());
- if (!prod_type)
- fail("DisplayID Base Block has no product type.\n");
- if (ext_count != dispid.preparsed_displayid_blocks - 1)
- fail("Expected %u DisplayID Extension Block%s, but got %u.\n",
- ext_count,
- ext_count > 1 ? "s" : "",
- dispid.preparsed_displayid_blocks - 1);
- } else {
- if (prod_type)
- fail("Product Type should be 0 in extension block.\n");
- if (ext_count)
- fail("Extension Count should be 0 in extension block.\n");
- if (version != dispid.version)
- fail("Got version %u.%u, expected %u.%u.\n",
- version >> 4, version & 0xf,
- dispid.version >> 4, dispid.version & 0xf);
- }
-
- if (length > 121) {
- fail("DisplayID length %d is greater than 121.\n", length);
- length = 121;
- }
-
- unsigned offset = 5;
- bool first_data_block = true;
- while (length > 0) {
unsigned tag = x[offset];
unsigned oui = 0;
@@ -1773,7 +1735,7 @@ void edid_state::parse_displayid_block(const unsigned char *x)
if (tag || x[offset + 1]) {
fail("Not enough bytes remain (%d) for a DisplayID data block or the DisplayID filler is non-0.\n", length);
}
- break;
+ return 0xff;
}
unsigned block_rev = x[offset + 1] & 0x07;
@@ -1781,7 +1743,7 @@ void edid_state::parse_displayid_block(const unsigned char *x)
if (length < len + 3) {
fail("The length of this DisplayID data block (%d) exceeds the number of bytes remaining (%d).\n", len + 3, length);
- break;
+ return 0xff;
}
if (!tag && !len) {
@@ -1789,7 +1751,7 @@ void edid_state::parse_displayid_block(const unsigned char *x)
if (!memchk(x + offset, length)) {
fail("Non-0 filler bytes in the DisplayID block.\n");
}
- break;
+ return 0xff;
}
printf(" %s:\n", data_block.c_str());
@@ -1925,12 +1887,57 @@ void edid_state::parse_displayid_block(const unsigned char *x)
}
if ((tag == 0x00 || tag == 0x20) &&
- (!dispid.is_base_block || !first_data_block))
+ (!dispid.is_base_block || dispid.block_number > 0))
fail("%s is required to be the first DisplayID Data Block.\n",
data_block.c_str());
+
+ dispid.block_number++;
+ return len;
+}
+
+void edid_state::parse_displayid_block(const unsigned char *x)
+{
+ unsigned version = x[1];
+ unsigned length = x[2];
+ unsigned prod_type = x[3]; // future check: based on type, check for required data blocks
+ unsigned ext_count = x[4];
+
+ printf(" Version: %u.%u\n Extension Count: %u\n",
+ version >> 4, version & 0xf, ext_count);
+
+ if (dispid.is_base_block) {
+ dispid.version = version;
+ printf(" %s: %s\n", product_type(prod_type, true).c_str(),
+ product_type(prod_type, false).c_str());
+ if (!prod_type)
+ fail("DisplayID Base Block has no product type.\n");
+ if (ext_count != dispid.preparsed_displayid_blocks - 1)
+ fail("Expected %u DisplayID Extension Block%s, but got %u.\n",
+ ext_count,
+ ext_count > 1 ? "s" : "",
+ dispid.preparsed_displayid_blocks - 1);
+ } else {
+ if (prod_type)
+ fail("Product Type should be 0 in extension block.\n");
+ if (ext_count)
+ fail("Extension Count should be 0 in extension block.\n");
+ if (version != dispid.version)
+ fail("Got version %u.%u, expected %u.%u.\n",
+ version >> 4, version & 0xf,
+ dispid.version >> 4, dispid.version & 0xf);
+ }
+
+ if (length > 121) {
+ fail("DisplayID length %d is greater than 121.\n", length);
+ length = 121;
+ }
+
+ unsigned offset = 5;
+ while (length > 0) {
+ unsigned len = displayid_block(version, x, offset, length);
+ if (len == 0xff) break;
length -= len + 3;
offset += len + 3;
- first_data_block = false;
}
/*
Move it to a new function displayid_block. Then we can simplify it later. This is mostly just a copy/paste. No output should change. The new function returns 0xff for len to signal a break from the loop in parse_displayid_block. That will be cleaned up later. first_data_block is replaced with dispid.block_number (similar to cta.block_number) Signed-off-by: Joe van Tunen <joevt@shaw.ca> --- edid-decode.h | 3 ++ parse-displayid-block.cpp | 95 +++++++++++++++++++++------------------ 2 files changed, 54 insertions(+), 44 deletions(-)