[PATCH] Parse the color management parts of the EDID

John Kåre Alsaker john.kare.alsaker at gmail.com
Thu May 2 14:09:43 PDT 2013


That will probably work.


On Thu, May 2, 2013 at 11:07 PM, Richard Hughes <hughsient at gmail.com> wrote:

> edid.[c|h] is actually what I had initially, want me to do something
> like that? Something like a:
>
> struct edid_info;
> int edid_parse(struct edid_info *info, const uint8_t *data, size_t length);
>
> Richard
>
> On 2 May 2013 21:57, John Kåre Alsaker <john.kare.alsaker at gmail.com>
> wrote:
> > EDID parsing should probably be moved out of compositor-drm since other
> > backends can provide EDIDs too.
> >
> >
> > On Thu, May 2, 2013 at 10:38 PM, Richard Hughes <hughsient at gmail.com>
> wrote:
> >>
> >> This code was originally written by Soren Sandmann <sandmann at redhat.com
> >
> >> and was
> >> found here: http://people.gnome.org/~ssp/randr/edid-parse.c
> >>
> >> The code has been in use in gnome-settings-daemon for a couple of years
> >> now and
> >> is used to generate an Auto-EDID ICC profile if the screen has not been
> >> profiled
> >> with a calibration device.
> >>
> >> This will be used by the CMS plugins in the future, and so it makes
> sense
> >> being
> >> common code in compositor-drm.
> >> ---
> >>  src/compositor-drm.c | 56
> >> ++++++++++++++++++++++++++++++++++++++++++++++++++++
> >>  1 file changed, 56 insertions(+)
> >>
> >> diff --git a/src/compositor-drm.c b/src/compositor-drm.c
> >> index f39096e..e4a1919 100644
> >> --- a/src/compositor-drm.c
> >> +++ b/src/compositor-drm.c
> >> @@ -136,11 +136,22 @@ struct drm_fb {
> >>         void *map;
> >>  };
> >>
> >> +struct drm_color_Yxy {
> >> +       double Y;
> >> +       double x;
> >> +       double y;
> >> +};
> >> +
> >>  struct drm_edid {
> >>         char eisa_id[13];
> >>         char monitor_name[13];
> >>         char pnp_id[5];
> >>         char serial_number[13];
> >> +       struct drm_color_Yxy whitepoint;
> >> +       struct drm_color_Yxy primary_red;
> >> +       struct drm_color_Yxy primary_green;
> >> +       struct drm_color_Yxy primary_blue;
> >> +       double gamma;
> >>  };
> >>
> >>  struct drm_output {
> >> @@ -1558,6 +1569,31 @@ edid_parse_string(const uint8_t *data, char
> text[])
> >>  #define EDID_OFFSET_SERIAL                             0x0c
> >>
> >>  static int
> >> +edid_get_bit(int in, int bit)
> >> +{
> >> +       return (in & (1 << bit)) >> bit;
> >> +}
> >> +
> >> +static int
> >> +edid_get_bits(int in, int begin, int end)
> >> +{
> >> +       int mask = (1 << (end - begin + 1)) - 1;
> >> +       return (in >> begin) & mask;
> >> +}
> >> +
> >> +static double
> >> +edid_decode_fraction(int high, int low)
> >> +{
> >> +       double result = 0.0;
> >> +       int i;
> >> +
> >> +       high = (high << 2) | low;
> >> +       for (i = 0; i < 10; ++i)
> >> +               result += edid_get_bit(high, i) * pow(2, i - 10);
> >> +       return result;
> >> +}
> >> +
> >> +static int
> >>  edid_parse(struct drm_edid *edid, const uint8_t *data, size_t length)
> >>  {
> >>         int i;
> >> @@ -1579,6 +1615,26 @@ edid_parse(struct drm_edid *edid, const uint8_t
> >> *data, size_t length)
> >>         edid->pnp_id[2] = 'A' + (data[EDID_OFFSET_PNPID + 1] & 0x1f) -
> 1;
> >>         edid->pnp_id[3] = '\0';
> >>
> >> +       /* get native gamma */
> >> +       if (data[0x17] == 0xff)
> >> +               edid->gamma = -1.0;
> >> +       else
> >> +               edid->gamma = (data[0x17] + 100.0) / 100.0;
> >> +
> >> +       /* get primaries and whitepoint */
> >> +       edid->primary_red.Y = 1.0f;
> >> +       edid->primary_red.x = edid_decode_fraction(data[0x1b],
> >> edid_get_bits(data[0x19], 6, 7));
> >> +       edid->primary_red.y = edid_decode_fraction(data[0x1c],
> >> edid_get_bits(data[0x19], 5, 4));
> >> +       edid->primary_green.Y = 1.0f;
> >> +       edid->primary_green.x = edid_decode_fraction(data[0x1d],
> >> edid_get_bits(data[0x19], 2, 3));
> >> +       edid->primary_green.y = edid_decode_fraction(data[0x1e],
> >> edid_get_bits(data[0x19], 0, 1));
> >> +       edid->primary_blue.Y = 1.0f;
> >> +       edid->primary_blue.x = edid_decode_fraction(data[0x1f],
> >> edid_get_bits(data[0x1a], 6, 7));
> >> +       edid->primary_blue.y = edid_decode_fraction(data[0x20],
> >> edid_get_bits(data[0x1a], 4, 5));
> >> +       edid->whitepoint.Y = 1.0f;
> >> +       edid->whitepoint.x = edid_decode_fraction(data[0x21],
> >> edid_get_bits(data[0x1a], 2, 3));
> >> +       edid->whitepoint.y = edid_decode_fraction(data[0x22],
> >> edid_get_bits(data[0x1a], 0, 1));
> >> +
> >>         /* maybe there isn't a ASCII serial number descriptor, so use
> this
> >> instead */
> >>         serial_number = (uint32_t) data[EDID_OFFSET_SERIAL + 0];
> >>         serial_number += (uint32_t) data[EDID_OFFSET_SERIAL + 1] *
> 0x100;
> >> --
> >> 1.8.2.1
> >>
> >> _______________________________________________
> >> wayland-devel mailing list
> >> wayland-devel at lists.freedesktop.org
> >> http://lists.freedesktop.org/mailman/listinfo/wayland-devel
> >
> >
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20130502/d61d0747/attachment-0001.html>


More information about the wayland-devel mailing list