mirror of
https://gitlab.freedesktop.org/emersion/libdisplay-info.git
synced 2024-11-16 19:48:30 +01:00
info: add di_info_get_default_color_primaries()
Add a high-level function to retrieve color primaries. Wayland compositors will be interested in this. A high-level function may later be extended to support stand-alone DisplayID and other sources. The high-level data is derived from low-level API calls in di_info_parse_edid(). As we stash the results in struct di_info to avoid requiring the callers to explicitly free the high-level structures, this allows keeping struct di_info deeply const in high-level API implementation. We also avoid some dynamic allocations. https://github.com/linuxhw/EDID.git database contains 20399 samples for which edid-decode complains: Basic Display Parameters & Features: sRGB is signaled, but the chromaticities do not match. Therefore I assume that the sRGB flag is more correct when set. Signed-off-by: Pekka Paalanen <pekka.paalanen@collabora.com>
This commit is contained in:
parent
7b4d87b2d2
commit
85043a07d5
3 changed files with 122 additions and 0 deletions
|
@ -7,10 +7,20 @@
|
|||
|
||||
#include <libdisplay-info/info.h>
|
||||
|
||||
/**
|
||||
* All information here is derived from low-level information contained in
|
||||
* struct di_info. These are exposed by the high-level API only.
|
||||
*/
|
||||
struct di_derived_info {
|
||||
struct di_color_primaries color_primaries;
|
||||
};
|
||||
|
||||
struct di_info {
|
||||
struct di_edid *edid;
|
||||
|
||||
char *failure_msg;
|
||||
|
||||
struct di_derived_info derived;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define DI_INFO_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* libdisplay-info's high-level API.
|
||||
|
@ -102,4 +103,52 @@ di_info_get_model(const struct di_info *info);
|
|||
char *
|
||||
di_info_get_serial(const struct di_info *info);
|
||||
|
||||
/** CIE 1931 2-degree observer chromaticity coordinates */
|
||||
struct di_chromaticity_cie1931 {
|
||||
float x;
|
||||
float y;
|
||||
};
|
||||
|
||||
/** Display color primaries and default white point */
|
||||
struct di_color_primaries {
|
||||
/* Are primary[] given */
|
||||
bool has_primaries;
|
||||
|
||||
/* Is default_white given */
|
||||
bool has_default_white_point;
|
||||
|
||||
/* Chromaticities of the primaries in RGB order
|
||||
*
|
||||
* Either all values are given, or they are all zeroes.
|
||||
*/
|
||||
struct di_chromaticity_cie1931 primary[3];
|
||||
|
||||
/* Default white point chromaticity
|
||||
*
|
||||
* If non-zero, this should be the display white point when it has
|
||||
* been reset to its factory defaults. Either both x and y are given,
|
||||
* or they are both zero.
|
||||
*/
|
||||
struct di_chromaticity_cie1931 default_white;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get display color primaries and default white point
|
||||
*
|
||||
* Get the parameters of the default RGB colorimetry mode which is always
|
||||
* supported. Primaries for monochrome displays might be all zeroes.
|
||||
*
|
||||
* These primaries might not be display's physical primaries, but only the
|
||||
* primaries of the default RGB colorimetry signal when using IT Video Format
|
||||
* (ANSI/CTA-861-H, Section 5).
|
||||
*
|
||||
* The returned pointer is owned by the struct di_info passed in. It remains
|
||||
* valid only as long as the di_info exists, and must not be freed by the
|
||||
* caller.
|
||||
*
|
||||
* This function does not return NULL.
|
||||
*/
|
||||
const struct di_color_primaries *
|
||||
di_info_get_default_color_primaries(const struct di_info *info);
|
||||
|
||||
#endif
|
||||
|
|
63
info.c
63
info.c
|
@ -11,6 +11,61 @@
|
|||
const char *
|
||||
pnp_id_table(const char *key);
|
||||
|
||||
static void
|
||||
derive_edid_color_primaries(const struct di_edid *edid,
|
||||
struct di_color_primaries *cc)
|
||||
{
|
||||
const struct di_edid_chromaticity_coords *cm;
|
||||
const struct di_edid_misc_features *misc;
|
||||
|
||||
/* Trust the flag more than the fields. */
|
||||
misc = di_edid_get_misc_features(edid);
|
||||
if (misc->srgb_is_primary) {
|
||||
/*
|
||||
* https://www.w3.org/Graphics/Color/sRGB.html
|
||||
* for lack of access to IEC 61966-2-1
|
||||
*/
|
||||
cc->primary[0].x = 0.640f; /* red */
|
||||
cc->primary[0].y = 0.330f;
|
||||
cc->primary[1].x = 0.300f; /* green */
|
||||
cc->primary[1].y = 0.600f;
|
||||
cc->primary[2].x = 0.150f; /* blue */
|
||||
cc->primary[2].y = 0.060f;
|
||||
cc->has_primaries = true;
|
||||
cc->default_white.x = 0.3127f; /* D65 */
|
||||
cc->default_white.y = 0.3290f;
|
||||
cc->has_default_white_point = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
cm = di_edid_get_chromaticity_coords(edid);
|
||||
|
||||
/*
|
||||
* Broken EDID might have only partial values.
|
||||
* Require all values to report anything.
|
||||
*/
|
||||
if (cm->red_x > 0.0f &&
|
||||
cm->red_y > 0.0f &&
|
||||
cm->green_x > 0.0f &&
|
||||
cm->green_y > 0.0f &&
|
||||
cm->blue_x > 0.0f &&
|
||||
cm->blue_y > 0.0f) {
|
||||
cc->primary[0].x = cm->red_x;
|
||||
cc->primary[0].y = cm->red_y;
|
||||
cc->primary[1].x = cm->green_x;
|
||||
cc->primary[1].y = cm->green_y;
|
||||
cc->primary[2].x = cm->blue_x;
|
||||
cc->primary[2].y = cm->blue_y;
|
||||
cc->has_primaries = true;
|
||||
}
|
||||
if (cm->white_x > 0.0f && cm->white_y > 0.0f) {
|
||||
cc->default_white.x = cm->white_x;
|
||||
cc->default_white.y = cm->white_y;
|
||||
cc->has_default_white_point = true;
|
||||
}
|
||||
}
|
||||
|
||||
struct di_info *
|
||||
di_info_parse_edid(const void *data, size_t size)
|
||||
{
|
||||
|
@ -38,6 +93,8 @@ di_info_parse_edid(const void *data, size_t size)
|
|||
else
|
||||
free(failure_msg_str);
|
||||
|
||||
derive_edid_color_primaries(info->edid, &info->derived.color_primaries);
|
||||
|
||||
return info;
|
||||
|
||||
err_edid:
|
||||
|
@ -194,3 +251,9 @@ di_info_get_serial(const struct di_info *info)
|
|||
memory_stream_cleanup(&m);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct di_color_primaries *
|
||||
di_info_get_default_color_primaries(const struct di_info *info)
|
||||
{
|
||||
return &info->derived.color_primaries;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue