GNOME Bugzilla – Bug 571254
Constructing a pixel value from components
Last modified: 2014-09-07 02:14:54 UTC
Documentation Section: gdk-Visuals.html guchar (i.e. ~8-bit) component arguments, right shifted by (16 - prec); later described as "constructing a pixel value out of three 16 bit color values" Correct version: I'd guess that the argument types should be at least 16 bits, say gushort's or guint16's. (Incidentally, I'd suggest hyphenating "16-bit", but no matter.) Other information: Excuse me for reporting more than one bug in a single bug report, but since it affects the same document: I'm fairly sure that the documentation for GDK_MSB_FIRST is wrong: that 0x00ffeecc is stored as 00, ff, ee, cc, not 00, cc, ee, ff as written.
Couldn't find the visual docs you complain about, but I corrected the GDK_MSB_FIRST issue.
(developer.gnome.org seems to have been recently rearranged, and there are several 404's when I try to find the corresponding gtk3 page; the following comment refers to http://developer.gnome.org/gdk/2.6/gdk-Visuals.html .) It looks like I was referring to "Example 5. Constructing a pixel value from components", which the documentation for red_shift describes as "show[ing] constructing a pixel value out of three 16 bit color values". Consider what the existing code in that example will do if red_prec (etc.) are all 8: the input 8-bit values will all be right-shifted by 8, thus discarding all the input, and returning 0 regardless of the supplied r,g,b values. Thus, I suggest changing the parameter types from guchar to guint16_t, and consider inserting the word "16-bit" into the title of the example. (An alternative would be to retain the guchar parameter types, and change "16 -" to "8 -" in the code, and change the description of this example in the documentation of red_shift from saying "16 bit" to "8-bit". Though see below.) I also believe that either there should be documentation as to the range of values that red_prec, red_shift etc. can take (e.g. that *_shift are guaranteed to be less than 32, i.e. that we'll never support more than 8 or 10 bits per channel), or else document and assert this assumption in the example code. That is, if we're to avoid undefined behaviour (in the C sense) in programs using these fields, then calling code must either use a test (perhaps using g_return_val_if_fail) before doing the shift, and/or must be assured in some other way that red_shift is non-negative and less than the number of bits in an int (or must use a type wider than an int, and must be assured that red_shift is less than the number of bits in that wider type). The example code is likely to be copied, so should follow best practices in this respect. This of course requires some decision as to how we want to support hardware that allows more than 8–10 bits per channel ("deep color"): whether we want it to be transparently supported by gdk apps using the normal GdkVisual apparatus (at the cost of code such as the example pixel_from_rgb using a 64-bit return type), or whether we want to limit things to 10 or 8 bits per channel to avoid bugs in apps that use code like the given example (this code will handle 10 bits per channel once changed to use 16-bit parameters, though maybe there's other application code that will truncate high bits when trying to stuff a component into a byte), or whether there should be some sort of opt-in mechanism where an app can declare that it can handle more than 8 or 10 bits per channel without bugs (e.g. that it uses 64-bit types for the likes of pixel_from_rgb's return type if it says that it can handle more than 10 bits per channel). As for display backends, it looks as though X supports at least 30-bit colour (e.g. I've seen references to at least intel and proprietary nvidia drivers support it), and I see at least some code (even if only EDID parsing) that makes provision for more than 10 bits per channel without writing a warning. Meanwhile, Windows supports up to 48bpp starting from Windows 7, and I believe MacOS has always (i.e. from when 24-bit colour was first supported) made some sort of provision for displays with up to 16 bits per channel. References: C99 sections 6.5.7 (shifts being undefined for negative or >= width of left operand after integer promotion) and 6.3.1.1 para 2 (integer promotion rules). “Deep color” section of http://en.wikipedia.org/wiki/Color_depth (and its “Industry support” subsection) gives some indication about degree of prevalence of support for 30 or >30 bits per pixel.
we don't have this information in the visual docs anymore (2.6 was looong ago, and is not going to get fixed anymore)