This is an automatic generated email to let you know that the following patch 
were queued:

Subject: edid-decode: improve image size checks
Author:  Hans Verkuil <[email protected]>
Date:    Sun Nov 7 15:47:42 2021 +0100

Carefully check if the image sizes in the base and DisplayID blocks
are consistent.

Signed-off-by: Hans Verkuil <[email protected]>

 edid-decode.h             |  7 +++++++
 parse-base-block.cpp      | 19 ++++++++++++-------
 parse-displayid-block.cpp | 40 +++++++++++++++++++++++++++++++++-------
 3 files changed, 52 insertions(+), 14 deletions(-)

---

diff --git a/edid-decode.h b/edid-decode.h
index 87cf662e6332..67e681a99e26 100644
--- a/edid-decode.h
+++ b/edid-decode.h
@@ -130,6 +130,7 @@ struct edid_state {
                warnings = failures = 0;
                has_cta = has_dispid = false;
                hide_serial_numbers = false;
+               image_width = image_height = 0;
 
                // Base block state
                base.edid_minor = 0;
@@ -178,6 +179,7 @@ struct edid_state {
                        dispid.has_display_parameters = dispid.has_type_1_7 =
                        dispid.has_display_interface_features = false;
                dispid.block_number = 0;
+               dispid.image_width = dispid.image_height = 0;
 
                // Block Map block state
                block_map.saw_block_1 = false;
@@ -202,6 +204,9 @@ struct edid_state {
        unsigned dtd_max_hsize_mm;
        unsigned dtd_max_vsize_mm;
 
+       // in 0.1 mm units
+       unsigned image_width, image_height;
+
        unsigned warnings;
        unsigned failures;
 
@@ -285,6 +290,8 @@ struct edid_state {
                bool has_display_interface_features;
                vec_timings_ext preferred_timings;
                unsigned native_width, native_height;
+               // in 0.1 mm units
+               unsigned image_width, image_height;
                unsigned block_number;
                // Keep track of the found CTA-861 Tag/Extended Tag pairs.
                // The unsigned value is equal to: (tag) | (OUI enum << 12) or 
(extended tag) | (tag << 8) | (OUI enum << 12)
diff --git a/parse-base-block.cpp b/parse-base-block.cpp
index 9e2ef4f3a036..048308b8701f 100644
--- a/parse-base-block.cpp
+++ b/parse-base-block.cpp
@@ -1442,6 +1442,8 @@ void edid_state::parse_base_block(const unsigned char *x)
                printf("    Maximum image size: %u cm x %u cm\n", x[0x15], 
x[0x16]);
                base.max_display_width_mm = x[0x15] * 10;
                base.max_display_height_mm = x[0x16] * 10;
+               image_width = base.max_display_width_mm * 10;
+               image_height = base.max_display_height_mm * 10;
                if (x[0x15] < 10 || x[0x16] < 10)
                        warn("Dubious maximum image size (%ux%u is smaller than 
10x10 cm).\n",
                             x[0x15], x[0x16]);
@@ -1701,13 +1703,16 @@ void edid_state::check_base_block()
                 */
                msg(!out_of_range || base.edid_minor >= 4, "%s", err.c_str());
        }
-       // The base block will only go up to 255x255 cm for the display size,
-       // so don't fail if one or more image sizes exceeds that.
-       if (!base.max_display_width_mm && !base.max_display_height_mm &&
-           dtd_max_hsize_mm && dtd_max_vsize_mm &&
-           dtd_max_hsize_mm <= 2559 && dtd_max_vsize_mm <= 2559) {
-               fail("The DTD image sizes all fit inside 255x255cm, but no 
display size was set.\n");
-       }
+
+       if ((image_width && dtd_max_hsize_mm >= 10 + image_width / 10) ||
+           (image_height && dtd_max_vsize_mm >= 10 + image_height / 10))
+               fail("The DTD max image size is %ux%umm, which is larger than 
the display size %.1fx%.1fmm.\n",
+                    dtd_max_hsize_mm, dtd_max_vsize_mm,
+                    image_width / 10.0, image_height / 10.0);
+       if ((!image_width && dtd_max_hsize_mm) || (!image_height && 
dtd_max_vsize_mm))
+               fail("The DTD max image size is %ux%umm, but the display size 
is not specified anywhere.\n",
+                    dtd_max_hsize_mm, dtd_max_vsize_mm);
+
        // Secondary GTF curves start at a specific frequency. Any legacy 
timings
        // that have a positive hsync and negative vsync must be less than that
        // frequency to avoid confusion.
diff --git a/parse-displayid-block.cpp b/parse-displayid-block.cpp
index ad5099f2239e..0f39830f7c56 100644
--- a/parse-displayid-block.cpp
+++ b/parse-displayid-block.cpp
@@ -157,10 +157,18 @@ void edid_state::parse_displayid_parameters(const 
unsigned char *x)
        if (!check_displayid_datablock_length(x, 12, 12))
                return;
 
+       if (dispid.has_display_parameters)
+               fail("Duplicate Display Parameters Data Block.\n");
        dispid.has_display_parameters = true;
+       dispid.image_width = (x[4] << 8) + x[3];
+       dispid.image_height = (x[6] << 8) + x[5];
+       if (dispid.image_width > image_width ||
+           dispid.image_height > image_height) {
+               image_width = dispid.image_width;
+               image_height = dispid.image_height;
+       }
        printf("    Image size: %.1f mm x %.1f mm\n",
-              ((x[4] << 8) + x[3]) / 10.0,
-              ((x[6] << 8) + x[5]) / 10.0);
+              dispid.image_width / 10.0, dispid.image_height / 10.0);
        unsigned w = (x[8] << 8) + x[7];
        unsigned h = (x[10] << 8) + x[9];
        printf("    Display native pixel format: %ux%u\n", w, h);
@@ -1130,17 +1138,29 @@ void edid_state::parse_displayid_parameters_v2(const 
unsigned char *x,
 {
        if (!check_displayid_datablock_length(x, 29, 29))
                return;
+       if (dispid.has_display_parameters)
+               fail("Duplicate Display Parameters Data Block.\n");
+       dispid.has_display_parameters = true;
 
        unsigned hor_size = (x[4] << 8) + x[3];
        unsigned vert_size = (x[6] << 8) + x[5];
 
-       dispid.has_display_parameters = true;
-       if (x[1] & 0x80)
-               printf("    Image size: %u mm x %u mm\n",
-                      hor_size, vert_size);
-       else
+       dispid.image_width = hor_size;
+       dispid.image_height = vert_size;
+       if (x[1] & 0x80) {
+               printf("    Image size: %u mm x %u mm\n", hor_size, vert_size);
+               dispid.image_width *= 10;
+               dispid.image_height *= 10;
+       } else {
                printf("    Image size: %.1f mm x %.1f mm\n",
                       hor_size / 10.0, vert_size / 10.0);
+       }
+       if (dispid.image_width > image_width ||
+           dispid.image_height > image_height) {
+               image_width = dispid.image_width;
+               image_height = dispid.image_height;
+       }
+
        unsigned w = (x[8] << 8) + x[7];
        unsigned h = (x[10] << 8) + x[9];
 
@@ -1980,4 +2000,10 @@ void edid_state::check_displayid_blocks()
                     dispid.version >= 0x20 ? "VII" : "I");
        if (dispid.preferred_timings.empty())
                fail("DisplayID expects at least one preferred timing.\n");
+       if (dispid.image_width && dispid.image_width < 25600 && 
dispid.image_height < 25600 &&
+           (abs((int)dispid.image_width - (int)base.max_display_width_mm * 10) 
>= 100 ||
+            abs((int)dispid.image_height - (int)base.max_display_height_mm * 
10) >= 100))
+               fail("Image size mismatch: DisplayID: %.1fx%.1fmm Base EDID: 
%u.0x%u.0mm.\n",
+                    dispid.image_width / 10.0, dispid.image_height / 10.0,
+                    base.max_display_width_mm, base.max_display_height_mm);
 }

_______________________________________________
linuxtv-commits mailing list
[email protected]
https://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to