EDID (VESA Enhanced Extended Display Identification Data): C++/STL parsing library

KS implementation details

License: CC0-1.0

This page hosts a formal specification of EDID (VESA Enhanced Extended Display Identification Data) using Kaitai Struct. This specification can be automatically translated into a variety of programming languages to get a parsing library.

Usage

Using Kaitai Struct in C++/STL usually consists of 3 steps.

  1. We need to create an STL input stream (std::istream).
    • One can open a stream for reading from a local file:
      #include <fstream>
      
      std::ifstream is("path/to/local/file.edid", std::ifstream::binary);
    • Or one can prepare a stream for reading from existing std::string str:
      #include <sstream>
      
      std::istringstream is(str);
    • Or one can parse arbitrary char* buffer in memory, given that we know its size:
      #include <sstream>
      
      const char buf[] = { ... };
      std::string str(buf, sizeof buf);
      std::istringstream is(str);
  2. We need to wrap our input stream into Kaitai stream:
    #include <kaitai/kaitaistream.h>
    
    kaitai::kstream ks(&is);
  3. And finally, we can invoke the parsing:
    edid_t data(&ks);

After that, one can get various attributes from the structure by invoking getter methods like:

data.product_code() // => Manufacturer product code

C++/STL source code to parse EDID (VESA Enhanced Extended Display Identification Data)

edid.h

#ifndef EDID_H_
#define EDID_H_

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

#include "kaitai/kaitaistruct.h"

#include <stdint.h>
#include <vector>

#if KAITAI_STRUCT_VERSION < 7000L
#error "Incompatible Kaitai Struct C++/STL API: version 0.7 or later is required"
#endif

class edid_t : public kaitai::kstruct {

public:
    class chromacity_info_t;
    class est_timings_info_t;
    class std_timing_t;

    edid_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent = 0, edid_t* p__root = 0);

private:
    void _read();

public:
    ~edid_t();

    /**
     * Chromaticity information: colorimetry and white point
     * coordinates. All coordinates are stored as fixed precision
     * 10-bit numbers, bits are shuffled for compactness.
     */

    class chromacity_info_t : public kaitai::kstruct {

    public:

        chromacity_info_t(kaitai::kstream* p__io, edid_t* p__parent = 0, edid_t* p__root = 0);

    private:
        void _read();

    public:
        ~chromacity_info_t();

    private:
        bool f_green_x_int;
        int32_t m_green_x_int;

    public:
        int32_t green_x_int();

    private:
        bool f_red_y;
        double m_red_y;

    public:

        /**
         * Red Y coordinate
         */
        double red_y();

    private:
        bool f_green_y_int;
        int32_t m_green_y_int;

    public:
        int32_t green_y_int();

    private:
        bool f_white_y;
        double m_white_y;

    public:

        /**
         * White Y coordinate
         */
        double white_y();

    private:
        bool f_red_x;
        double m_red_x;

    public:

        /**
         * Red X coordinate
         */
        double red_x();

    private:
        bool f_white_x;
        double m_white_x;

    public:

        /**
         * White X coordinate
         */
        double white_x();

    private:
        bool f_blue_x;
        double m_blue_x;

    public:

        /**
         * Blue X coordinate
         */
        double blue_x();

    private:
        bool f_white_x_int;
        int32_t m_white_x_int;

    public:
        int32_t white_x_int();

    private:
        bool f_white_y_int;
        int32_t m_white_y_int;

    public:
        int32_t white_y_int();

    private:
        bool f_green_x;
        double m_green_x;

    public:

        /**
         * Green X coordinate
         */
        double green_x();

    private:
        bool f_red_x_int;
        int32_t m_red_x_int;

    public:
        int32_t red_x_int();

    private:
        bool f_red_y_int;
        int32_t m_red_y_int;

    public:
        int32_t red_y_int();

    private:
        bool f_blue_x_int;
        int32_t m_blue_x_int;

    public:
        int32_t blue_x_int();

    private:
        bool f_blue_y;
        double m_blue_y;

    public:

        /**
         * Blue Y coordinate
         */
        double blue_y();

    private:
        bool f_green_y;
        double m_green_y;

    public:

        /**
         * Green Y coordinate
         */
        double green_y();

    private:
        bool f_blue_y_int;
        int32_t m_blue_y_int;

    public:
        int32_t blue_y_int();

    private:
        uint64_t m_red_x_1_0;
        uint64_t m_red_y_1_0;
        uint64_t m_green_x_1_0;
        uint64_t m_green_y_1_0;
        uint64_t m_blue_x_1_0;
        uint64_t m_blue_y_1_0;
        uint64_t m_white_x_1_0;
        uint64_t m_white_y_1_0;
        uint8_t m_red_x_9_2;
        uint8_t m_red_y_9_2;
        uint8_t m_green_x_9_2;
        uint8_t m_green_y_9_2;
        uint8_t m_blue_x_9_2;
        uint8_t m_blue_y_9_2;
        uint8_t m_white_x_9_2;
        uint8_t m_white_y_9_2;
        edid_t* m__root;
        edid_t* m__parent;

    public:

        /**
         * Red X, bits 1..0
         */
        uint64_t red_x_1_0() const { return m_red_x_1_0; }

        /**
         * Red Y, bits 1..0
         */
        uint64_t red_y_1_0() const { return m_red_y_1_0; }

        /**
         * Green X, bits 1..0
         */
        uint64_t green_x_1_0() const { return m_green_x_1_0; }

        /**
         * Green Y, bits 1..0
         */
        uint64_t green_y_1_0() const { return m_green_y_1_0; }

        /**
         * Blue X, bits 1..0
         */
        uint64_t blue_x_1_0() const { return m_blue_x_1_0; }

        /**
         * Blue Y, bits 1..0
         */
        uint64_t blue_y_1_0() const { return m_blue_y_1_0; }

        /**
         * White X, bits 1..0
         */
        uint64_t white_x_1_0() const { return m_white_x_1_0; }

        /**
         * White Y, bits 1..0
         */
        uint64_t white_y_1_0() const { return m_white_y_1_0; }

        /**
         * Red X, bits 9..2
         */
        uint8_t red_x_9_2() const { return m_red_x_9_2; }

        /**
         * Red Y, bits 9..2
         */
        uint8_t red_y_9_2() const { return m_red_y_9_2; }

        /**
         * Green X, bits 9..2
         */
        uint8_t green_x_9_2() const { return m_green_x_9_2; }

        /**
         * Green Y, bits 9..2
         */
        uint8_t green_y_9_2() const { return m_green_y_9_2; }

        /**
         * Blue X, bits 9..2
         */
        uint8_t blue_x_9_2() const { return m_blue_x_9_2; }

        /**
         * Blue Y, bits 9..2
         */
        uint8_t blue_y_9_2() const { return m_blue_y_9_2; }

        /**
         * White X, bits 9..2
         */
        uint8_t white_x_9_2() const { return m_white_x_9_2; }

        /**
         * White Y, bits 9..2
         */
        uint8_t white_y_9_2() const { return m_white_y_9_2; }
        edid_t* _root() const { return m__root; }
        edid_t* _parent() const { return m__parent; }
    };

    class est_timings_info_t : public kaitai::kstruct {

    public:

        est_timings_info_t(kaitai::kstream* p__io, edid_t* p__parent = 0, edid_t* p__root = 0);

    private:
        void _read();

    public:
        ~est_timings_info_t();

    private:
        bool m_can_720_400_70;
        bool m_can_720_400_88;
        bool m_can_640_480_60;
        bool m_can_640_480_67;
        bool m_can_640_480_72;
        bool m_can_640_480_75;
        bool m_can_800_600_56;
        bool m_can_800_600_60;
        bool m_can_800_600_72;
        bool m_can_800_600_75;
        bool m_can_832_624_75;
        bool m_can_1024_768_87_i;
        bool m_can_1024_768_60;
        bool m_can_1024_768_70;
        bool m_can_1024_768_75;
        bool m_can_1280_1024_75;
        bool m_can_1152_870_75;
        uint64_t m_reserved;
        edid_t* m__root;
        edid_t* m__parent;

    public:

        /**
         * Supports 720 x 400 @ 70Hz
         */
        bool can_720_400_70() const { return m_can_720_400_70; }

        /**
         * Supports 720 x 400 @ 88Hz
         */
        bool can_720_400_88() const { return m_can_720_400_88; }

        /**
         * Supports 640 x 480 @ 60Hz
         */
        bool can_640_480_60() const { return m_can_640_480_60; }

        /**
         * Supports 640 x 480 @ 67Hz
         */
        bool can_640_480_67() const { return m_can_640_480_67; }

        /**
         * Supports 640 x 480 @ 72Hz
         */
        bool can_640_480_72() const { return m_can_640_480_72; }

        /**
         * Supports 640 x 480 @ 75Hz
         */
        bool can_640_480_75() const { return m_can_640_480_75; }

        /**
         * Supports 800 x 600 @ 56Hz
         */
        bool can_800_600_56() const { return m_can_800_600_56; }

        /**
         * Supports 800 x 600 @ 60Hz
         */
        bool can_800_600_60() const { return m_can_800_600_60; }

        /**
         * Supports 800 x 600 @ 72Hz
         */
        bool can_800_600_72() const { return m_can_800_600_72; }

        /**
         * Supports 800 x 600 @ 75Hz
         */
        bool can_800_600_75() const { return m_can_800_600_75; }

        /**
         * Supports 832 x 624 @ 75Hz
         */
        bool can_832_624_75() const { return m_can_832_624_75; }

        /**
         * Supports 1024 x 768 @ 87Hz(I)
         */
        bool can_1024_768_87_i() const { return m_can_1024_768_87_i; }

        /**
         * Supports 1024 x 768 @ 60Hz
         */
        bool can_1024_768_60() const { return m_can_1024_768_60; }

        /**
         * Supports 1024 x 768 @ 70Hz
         */
        bool can_1024_768_70() const { return m_can_1024_768_70; }

        /**
         * Supports 1024 x 768 @ 75Hz
         */
        bool can_1024_768_75() const { return m_can_1024_768_75; }

        /**
         * Supports 1280 x 1024 @ 75Hz
         */
        bool can_1280_1024_75() const { return m_can_1280_1024_75; }

        /**
         * Supports 1152 x 870 @ 75Hz
         */
        bool can_1152_870_75() const { return m_can_1152_870_75; }
        uint64_t reserved() const { return m_reserved; }
        edid_t* _root() const { return m__root; }
        edid_t* _parent() const { return m__parent; }
    };

    class std_timing_t : public kaitai::kstruct {

    public:

        enum aspect_ratios_t {
            ASPECT_RATIOS_RATIO_16_10 = 0,
            ASPECT_RATIOS_RATIO_4_3 = 1,
            ASPECT_RATIOS_RATIO_5_4 = 2,
            ASPECT_RATIOS_RATIO_16_9 = 3
        };

        std_timing_t(kaitai::kstream* p__io, edid_t* p__parent = 0, edid_t* p__root = 0);

    private:
        void _read();

    public:
        ~std_timing_t();

    private:
        bool f_horiz_active_pixels;
        int32_t m_horiz_active_pixels;

    public:

        /**
         * Range of horizontal active pixels.
         */
        int32_t horiz_active_pixels();

    private:
        bool f_refresh_rate;
        int32_t m_refresh_rate;

    public:

        /**
         * Vertical refresh rate, Hz.
         */
        int32_t refresh_rate();

    private:
        uint8_t m_horiz_active_pixels_mod;
        aspect_ratios_t m_aspect_ratio;
        uint64_t m_refresh_rate_mod;
        edid_t* m__root;
        edid_t* m__parent;

    public:

        /**
         * Range of horizontal active pixels, written in modified form:
         * `(horiz_active_pixels / 8) - 31`. This yields an effective
         * range of 256..2288, with steps of 8 pixels.
         */
        uint8_t horiz_active_pixels_mod() const { return m_horiz_active_pixels_mod; }

        /**
         * Aspect ratio of the image. Can be used to calculate number
         * of vertical pixels.
         */
        aspect_ratios_t aspect_ratio() const { return m_aspect_ratio; }

        /**
         * Refresh rate in Hz, written in modified form: `refresh_rate
         * - 60`. This yields an effective range of 60..123 Hz.
         */
        uint64_t refresh_rate_mod() const { return m_refresh_rate_mod; }
        edid_t* _root() const { return m__root; }
        edid_t* _parent() const { return m__parent; }
    };

private:
    bool f_mfg_year;
    int32_t m_mfg_year;

public:
    int32_t mfg_year();

private:
    bool f_mfg_id_ch1;
    int32_t m_mfg_id_ch1;

public:
    int32_t mfg_id_ch1();

private:
    bool f_mfg_id_ch3;
    int32_t m_mfg_id_ch3;

public:
    int32_t mfg_id_ch3();

private:
    bool f_gamma;
    double m_gamma;
    bool n_gamma;

public:
    bool _is_null_gamma() { gamma(); return n_gamma; };

private:

public:
    double gamma();

private:
    bool f_mfg_id_ch2;
    int32_t m_mfg_id_ch2;

public:
    int32_t mfg_id_ch2();

private:
    std::string m_magic;
    uint16_t m_mfg_bytes;
    uint16_t m_product_code;
    uint32_t m_serial;
    uint8_t m_mfg_week;
    uint8_t m_mfg_year_mod;
    uint8_t m_edid_version_major;
    uint8_t m_edid_version_minor;
    uint8_t m_input_flags;
    uint8_t m_screen_size_h;
    uint8_t m_screen_size_v;
    uint8_t m_gamma_mod;
    uint8_t m_features_flags;
    chromacity_info_t* m_chromacity;
    est_timings_info_t* m_est_timings;
    std::vector<std_timing_t*>* m_std_timings;
    edid_t* m__root;
    kaitai::kstruct* m__parent;

public:
    std::string magic() const { return m_magic; }
    uint16_t mfg_bytes() const { return m_mfg_bytes; }

    /**
     * Manufacturer product code
     */
    uint16_t product_code() const { return m_product_code; }

    /**
     * Serial number
     */
    uint32_t serial() const { return m_serial; }

    /**
     * Week of manufacture. Week numbering is not consistent between manufacturers.
     */
    uint8_t mfg_week() const { return m_mfg_week; }

    /**
     * Year of manufacture, less 1990. (1990???2245). If week=255, it is the model year instead.
     */
    uint8_t mfg_year_mod() const { return m_mfg_year_mod; }

    /**
     * EDID version, usually 1 (for 1.3)
     */
    uint8_t edid_version_major() const { return m_edid_version_major; }

    /**
     * EDID revision, usually 3 (for 1.3)
     */
    uint8_t edid_version_minor() const { return m_edid_version_minor; }
    uint8_t input_flags() const { return m_input_flags; }

    /**
     * Maximum horizontal image size, in centimetres (max 292 cm/115 in at 16:9 aspect ratio)
     */
    uint8_t screen_size_h() const { return m_screen_size_h; }

    /**
     * Maximum vertical image size, in centimetres. If either byte is 0, undefined (e.g. projector)
     */
    uint8_t screen_size_v() const { return m_screen_size_v; }

    /**
     * Display gamma, datavalue = (gamma*100)-100 (range 1.00???3.54)
     */
    uint8_t gamma_mod() const { return m_gamma_mod; }
    uint8_t features_flags() const { return m_features_flags; }

    /**
     * Phosphor or filter chromaticity structure, which provides info on colorimetry and white point
     * \sa Standard, section 3.7
     */
    chromacity_info_t* chromacity() const { return m_chromacity; }

    /**
     * Block of bit flags that indicates support of so called
     * "established timings", which is a commonly used subset of VESA
     * DMT (Discrete Monitor Timings) modes.
     * \sa Standard, section 3.8
     */
    est_timings_info_t* est_timings() const { return m_est_timings; }

    /**
     * Array of descriptions of so called "standard timings", which are
     * used to specify up to 8 additional timings not included in
     * "established timings".
     */
    std::vector<std_timing_t*>* std_timings() const { return m_std_timings; }
    edid_t* _root() const { return m__root; }
    kaitai::kstruct* _parent() const { return m__parent; }
};

#endif  // EDID_H_

edid.cpp

// This is a generated file! Please edit source .ksy file and use kaitai-struct-compiler to rebuild

#include "edid.h"



edid_t::edid_t(kaitai::kstream* p__io, kaitai::kstruct* p__parent, edid_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = this;
    f_mfg_year = false;
    f_mfg_id_ch1 = false;
    f_mfg_id_ch3 = false;
    f_gamma = false;
    f_mfg_id_ch2 = false;
    _read();
}

void edid_t::_read() {
    m_magic = m__io->ensure_fixed_contents(std::string("\x00\xFF\xFF\xFF\xFF\xFF\xFF\x00", 8));
    m_mfg_bytes = m__io->read_u2le();
    m_product_code = m__io->read_u2le();
    m_serial = m__io->read_u4le();
    m_mfg_week = m__io->read_u1();
    m_mfg_year_mod = m__io->read_u1();
    m_edid_version_major = m__io->read_u1();
    m_edid_version_minor = m__io->read_u1();
    m_input_flags = m__io->read_u1();
    m_screen_size_h = m__io->read_u1();
    m_screen_size_v = m__io->read_u1();
    m_gamma_mod = m__io->read_u1();
    m_features_flags = m__io->read_u1();
    m_chromacity = new chromacity_info_t(m__io, this, m__root);
    m_est_timings = new est_timings_info_t(m__io, this, m__root);
    int l_std_timings = 8;
    m_std_timings = new std::vector<std_timing_t*>();
    m_std_timings->reserve(l_std_timings);
    for (int i = 0; i < l_std_timings; i++) {
        m_std_timings->push_back(new std_timing_t(m__io, this, m__root));
    }
}

edid_t::~edid_t() {
    delete m_chromacity;
    delete m_est_timings;
    for (std::vector<std_timing_t*>::iterator it = m_std_timings->begin(); it != m_std_timings->end(); ++it) {
        delete *it;
    }
    delete m_std_timings;
}

edid_t::chromacity_info_t::chromacity_info_t(kaitai::kstream* p__io, edid_t* p__parent, edid_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    f_green_x_int = false;
    f_red_y = false;
    f_green_y_int = false;
    f_white_y = false;
    f_red_x = false;
    f_white_x = false;
    f_blue_x = false;
    f_white_x_int = false;
    f_white_y_int = false;
    f_green_x = false;
    f_red_x_int = false;
    f_red_y_int = false;
    f_blue_x_int = false;
    f_blue_y = false;
    f_green_y = false;
    f_blue_y_int = false;
    _read();
}

void edid_t::chromacity_info_t::_read() {
    m_red_x_1_0 = m__io->read_bits_int(2);
    m_red_y_1_0 = m__io->read_bits_int(2);
    m_green_x_1_0 = m__io->read_bits_int(2);
    m_green_y_1_0 = m__io->read_bits_int(2);
    m_blue_x_1_0 = m__io->read_bits_int(2);
    m_blue_y_1_0 = m__io->read_bits_int(2);
    m_white_x_1_0 = m__io->read_bits_int(2);
    m_white_y_1_0 = m__io->read_bits_int(2);
    m__io->align_to_byte();
    m_red_x_9_2 = m__io->read_u1();
    m_red_y_9_2 = m__io->read_u1();
    m_green_x_9_2 = m__io->read_u1();
    m_green_y_9_2 = m__io->read_u1();
    m_blue_x_9_2 = m__io->read_u1();
    m_blue_y_9_2 = m__io->read_u1();
    m_white_x_9_2 = m__io->read_u1();
    m_white_y_9_2 = m__io->read_u1();
}

edid_t::chromacity_info_t::~chromacity_info_t() {
}

int32_t edid_t::chromacity_info_t::green_x_int() {
    if (f_green_x_int)
        return m_green_x_int;
    m_green_x_int = ((green_x_9_2() << 2) | green_x_1_0());
    f_green_x_int = true;
    return m_green_x_int;
}

double edid_t::chromacity_info_t::red_y() {
    if (f_red_y)
        return m_red_y;
    m_red_y = (red_y_int() / 1024.0);
    f_red_y = true;
    return m_red_y;
}

int32_t edid_t::chromacity_info_t::green_y_int() {
    if (f_green_y_int)
        return m_green_y_int;
    m_green_y_int = ((green_y_9_2() << 2) | green_y_1_0());
    f_green_y_int = true;
    return m_green_y_int;
}

double edid_t::chromacity_info_t::white_y() {
    if (f_white_y)
        return m_white_y;
    m_white_y = (white_y_int() / 1024.0);
    f_white_y = true;
    return m_white_y;
}

double edid_t::chromacity_info_t::red_x() {
    if (f_red_x)
        return m_red_x;
    m_red_x = (red_x_int() / 1024.0);
    f_red_x = true;
    return m_red_x;
}

double edid_t::chromacity_info_t::white_x() {
    if (f_white_x)
        return m_white_x;
    m_white_x = (white_x_int() / 1024.0);
    f_white_x = true;
    return m_white_x;
}

double edid_t::chromacity_info_t::blue_x() {
    if (f_blue_x)
        return m_blue_x;
    m_blue_x = (blue_x_int() / 1024.0);
    f_blue_x = true;
    return m_blue_x;
}

int32_t edid_t::chromacity_info_t::white_x_int() {
    if (f_white_x_int)
        return m_white_x_int;
    m_white_x_int = ((white_x_9_2() << 2) | white_x_1_0());
    f_white_x_int = true;
    return m_white_x_int;
}

int32_t edid_t::chromacity_info_t::white_y_int() {
    if (f_white_y_int)
        return m_white_y_int;
    m_white_y_int = ((white_y_9_2() << 2) | white_y_1_0());
    f_white_y_int = true;
    return m_white_y_int;
}

double edid_t::chromacity_info_t::green_x() {
    if (f_green_x)
        return m_green_x;
    m_green_x = (green_x_int() / 1024.0);
    f_green_x = true;
    return m_green_x;
}

int32_t edid_t::chromacity_info_t::red_x_int() {
    if (f_red_x_int)
        return m_red_x_int;
    m_red_x_int = ((red_x_9_2() << 2) | red_x_1_0());
    f_red_x_int = true;
    return m_red_x_int;
}

int32_t edid_t::chromacity_info_t::red_y_int() {
    if (f_red_y_int)
        return m_red_y_int;
    m_red_y_int = ((red_y_9_2() << 2) | red_y_1_0());
    f_red_y_int = true;
    return m_red_y_int;
}

int32_t edid_t::chromacity_info_t::blue_x_int() {
    if (f_blue_x_int)
        return m_blue_x_int;
    m_blue_x_int = ((blue_x_9_2() << 2) | blue_x_1_0());
    f_blue_x_int = true;
    return m_blue_x_int;
}

double edid_t::chromacity_info_t::blue_y() {
    if (f_blue_y)
        return m_blue_y;
    m_blue_y = (blue_y_int() / 1024.0);
    f_blue_y = true;
    return m_blue_y;
}

double edid_t::chromacity_info_t::green_y() {
    if (f_green_y)
        return m_green_y;
    m_green_y = (green_y_int() / 1024.0);
    f_green_y = true;
    return m_green_y;
}

int32_t edid_t::chromacity_info_t::blue_y_int() {
    if (f_blue_y_int)
        return m_blue_y_int;
    m_blue_y_int = ((blue_y_9_2() << 2) | blue_y_1_0());
    f_blue_y_int = true;
    return m_blue_y_int;
}

edid_t::est_timings_info_t::est_timings_info_t(kaitai::kstream* p__io, edid_t* p__parent, edid_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    _read();
}

void edid_t::est_timings_info_t::_read() {
    m_can_720_400_70 = m__io->read_bits_int(1);
    m_can_720_400_88 = m__io->read_bits_int(1);
    m_can_640_480_60 = m__io->read_bits_int(1);
    m_can_640_480_67 = m__io->read_bits_int(1);
    m_can_640_480_72 = m__io->read_bits_int(1);
    m_can_640_480_75 = m__io->read_bits_int(1);
    m_can_800_600_56 = m__io->read_bits_int(1);
    m_can_800_600_60 = m__io->read_bits_int(1);
    m_can_800_600_72 = m__io->read_bits_int(1);
    m_can_800_600_75 = m__io->read_bits_int(1);
    m_can_832_624_75 = m__io->read_bits_int(1);
    m_can_1024_768_87_i = m__io->read_bits_int(1);
    m_can_1024_768_60 = m__io->read_bits_int(1);
    m_can_1024_768_70 = m__io->read_bits_int(1);
    m_can_1024_768_75 = m__io->read_bits_int(1);
    m_can_1280_1024_75 = m__io->read_bits_int(1);
    m_can_1152_870_75 = m__io->read_bits_int(1);
    m_reserved = m__io->read_bits_int(7);
}

edid_t::est_timings_info_t::~est_timings_info_t() {
}

edid_t::std_timing_t::std_timing_t(kaitai::kstream* p__io, edid_t* p__parent, edid_t* p__root) : kaitai::kstruct(p__io) {
    m__parent = p__parent;
    m__root = p__root;
    f_horiz_active_pixels = false;
    f_refresh_rate = false;
    _read();
}

void edid_t::std_timing_t::_read() {
    m_horiz_active_pixels_mod = m__io->read_u1();
    m_aspect_ratio = static_cast<edid_t::std_timing_t::aspect_ratios_t>(m__io->read_bits_int(2));
    m_refresh_rate_mod = m__io->read_bits_int(5);
}

edid_t::std_timing_t::~std_timing_t() {
}

int32_t edid_t::std_timing_t::horiz_active_pixels() {
    if (f_horiz_active_pixels)
        return m_horiz_active_pixels;
    m_horiz_active_pixels = ((horiz_active_pixels_mod() + 31) * 8);
    f_horiz_active_pixels = true;
    return m_horiz_active_pixels;
}

int32_t edid_t::std_timing_t::refresh_rate() {
    if (f_refresh_rate)
        return m_refresh_rate;
    m_refresh_rate = (refresh_rate_mod() + 60);
    f_refresh_rate = true;
    return m_refresh_rate;
}

int32_t edid_t::mfg_year() {
    if (f_mfg_year)
        return m_mfg_year;
    m_mfg_year = (mfg_year_mod() + 1990);
    f_mfg_year = true;
    return m_mfg_year;
}

int32_t edid_t::mfg_id_ch1() {
    if (f_mfg_id_ch1)
        return m_mfg_id_ch1;
    m_mfg_id_ch1 = ((mfg_bytes() & 31744) >> 10);
    f_mfg_id_ch1 = true;
    return m_mfg_id_ch1;
}

int32_t edid_t::mfg_id_ch3() {
    if (f_mfg_id_ch3)
        return m_mfg_id_ch3;
    m_mfg_id_ch3 = (mfg_bytes() & 31);
    f_mfg_id_ch3 = true;
    return m_mfg_id_ch3;
}

double edid_t::gamma() {
    if (f_gamma)
        return m_gamma;
    n_gamma = true;
    if (gamma_mod() != 255) {
        n_gamma = false;
        m_gamma = ((gamma_mod() + 100) / 100.0);
    }
    f_gamma = true;
    return m_gamma;
}

int32_t edid_t::mfg_id_ch2() {
    if (f_mfg_id_ch2)
        return m_mfg_id_ch2;
    m_mfg_id_ch2 = ((mfg_bytes() & 992) >> 5);
    f_mfg_id_ch2 = true;
    return m_mfg_id_ch2;
}