I'm trying to piece together the truth about color spaces on OS X 10.7 and 10.8. There's so much documentation of varying age that I'm not sure what's correct anymore.
My current understanding is this: Since 10.4, Quartz does not support the concept of a device color space _at all_. That is to say, you cannot create a bitmap context and assign a color space such that drawing RGB(128,0,0) is guaranteed to feed RGB(128,0,0) to the graphics hardware. If you continue to ask for a Device color space, Quartz will instead give you a "Generic" color space. The generic color space is described in QA 1396 and an email to the quartz-dev mailing list [1] as an ICC-based color profile that represents the "gold standard" to which Apple monitors strived in 2005, the definition of which lives at '/System/Library/ColorSync/Profiles/Generic <Color Space Model>.icc'. When 10.6 came around, the definition of the Generic RGB color space (and thus the profile at …/Generic RGB.icc) was updated with a gamma of 2.2 instead of 1.8. That thread recommends using CGLayerRefs for offscreen drawing, since you don't have to specify its color space. But we know that CGLayerRefs are almost entirely useless. [2] I assume creating a CGLayerRef from a graphics context just uses whatever color space the graphics context uses, so it would not have been wise to create a CGLayerRef hang onto it forever, given that the color space of the device context can change. So the best approach for caching offscreen drawing using Quartz nowadays is to draw into a CGBitmapContext with a Generic color space, and then draw that bitmap into your destination context when needed, at which point Quartz will perform color conversion into the window's color space. This means that unlike a CGLayerRef, you can create the bitmap once and stamp it into whatever context you want, and you should get the same appearance in all places. There's one unresolved inconsistency: the docs for CGImageCreateWithMask say: """If the mask is an image, it must be in the DeviceGray color space, must not have an alpha component, and may not itself be masked by an image mask or a masking color.""" I guess this just some documentation that hasn't been updated since device color spaces were deprecated. Enter Cocoa. The AppKit release notes for 10.4 say the following: [3] """Calibrated NSColors (those created with colorWithCalibratedRed:.., colorWithCalibratedHue:.., or colorWithCalibratedWhite:...) now use Quartz generic color spaces, rather than the "display" (aka "device") color spaces. For debugging purposes this behavior can be disabled with the NSUseGenericColorSpaceForCalibrated default. This is a debugging default and will be removed in a future update. In applications, the proper way to get the device color space behavior is to create colors with colorWithDeviceRed:..., colorWithDeviceWhite:..., etc. In many cases, as appropriate, the underlying color for NSColors representing colors used in the user interface (for instance, methods such as -[NSColor alternateSelectedControlColor]) has been changed to device color space.""" I'm trying to rectify this with my understanding of the situation as it pertains to Quartz. I suppose the implication of the first paragraph was that in 10.3 and earlier +colorWithCalibrated{Blah} actually invoked ColorSync to calculate the calibrated colors for the specific output device. Since 10.4, the named color space NSCalibrated<Model>ColorSpace maps to kCGColorSpaceGeneric<Model>. The second paragraph still baffles me. So +colorWithDevice{Blah}:… is somehow able to give me a color in device color space, despite Quartz not supporting that concept? Or does it just pick a specific device at the time of the cal and use that device's ICC-based color space? Or does AppKit drawing do something like reinterpret the color values of an NSDevice<Model>ColorSpace as values in the color space of the current NSGraphicsContext? Finally, the AppKit release notes for 10.7 [3] say this: """NSColor now has two class methods to enable creating colors with sRGB or its gray counterpart color spaces. These create colors with colorSpaceName = NSCustomColorSpace and the appropriate color space (+[NSColorSpace sRGBColorSpace] or +[NSColorSpace genericGamma22GrayColorSpace]). These days the sRGB color space is a better match to the default Mac display environment than the calibrated color space. For this reason in general we recommend using sRGB color space for your images and in your colors—this can lead to better fidelity and performance.""" The implication here is that Apple's recent display hardware is targeting the sRGB gamut. How does this relate to, say, choosing color constants for UI? --Kyle Sluder [1] http://lists.apple.com/archives/quartz-dev/2005/May/msg00110.html [2] http://blog.metaobject.com/2012/11/cglayer-performance-and-quality.html _______________________________________________ Cocoa-dev mailing list (Cocoa-dev@lists.apple.com) Please do not post admin requests or moderator comments to the list. Contact the moderators at cocoa-dev-admins(at)lists.apple.com Help/Unsubscribe/Update your Subscription: https://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com This email sent to arch...@mail-archive.com