diff mbox series

[v2,18/29] edid-decode: move parse_displayid_block inner loop

Message ID 20210926083330.5206-19-joevt@shaw.ca (mailing list archive)
State New, archived
Headers show
Series edid-decode: bug fixes, additions, changes | expand

Commit Message

joevt Sept. 26, 2021, 8:33 a.m. UTC
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(-)
diff mbox series

Patch

diff --git a/edid-decode.h b/edid-decode.h
index dbc00c2..4636978 100644
--- a/edid-decode.h
+++ b/edid-decode.h
@@ -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);
diff --git a/parse-displayid-block.cpp b/parse-displayid-block.cpp
index e4c3bff..0a996bd 100644
--- a/parse-displayid-block.cpp
+++ b/parse-displayid-block.cpp
@@ -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;
 	}
 
 	/*