State of CGColorSpace APIs & Color Management on iOS?

997 views Asked by At

I'm currently trying to wrap my head around the current state of the CGColorSpace Color Management APIs on iOS. Prior to the iOS 8.1 SDK (as far as I can tell) many of the functions & constants in CGColorSpace.h were labeled as __IPHONE_NA. However, according the the iOS 8.1 API Diffs for Core Graphics many of the functions & constants that were previously __IPHONE_NA were updated to __IPHONE_2_0. So how are we supposed to interpret that?

I don't think Apple retroactively added support for those functions to old iOS releases, rather they just changed those functions' visibility from private to public. The problems come when trying to use some of those functions on different iOS versions & devices. For example:

CGColorSpaceRef sRgb = CGColorSpaceCreateWithName( kCGColorSpaceSRGB ); // kCGColorSpaceSRGB is labeled __IPHONE_8_0  
CFDataRef   profData = CGColorSpaceCopyICCProfile( ... );  
  • On an iPad Mini (original) running iOS 8.2: sRgb & profData will be NULL.
  • On an iPad 3 running iOS 8.3: sRgb & profData will be NULL.
  • On an iPhone 6 Plus running iOS 9.2.1: sRgb will contain a non-NULL CGColorSpaceRef, profData will contain a non-NULL CFDataRef buffer.
  • On an iPad Mini (original) running iOS 9.2.1: sRgb will contain a non-NULL CGColorSpaceRef, profData will contain a non-NULL CFDataRef buffer.

So at least for iOS 8 it appears that these functions aren't completely implemented. For iOS 9 things appear to start working.

Are there any documentation or resources that describe how these APIs changed in iOS 8 and iOS 9? What color space should be used when CGColorSpaceCreateWithName( kCGColorSpaceSRGB ) returns NULL? It seems like CGColorSpaceCreateDeviceRGB() may be the only option in that case.

After some testing I’ve found that it is possible to get the embedded color profile from a CGImageRef and use that profile to apply a color transform to another color space, as long as you do the color transform yourself. The Core Graphics APIs still don’t support transforming images between color spaces, but if you have your own Color Management functions it is now possible to do it yourself on iOS - something that wasn’t possible before.

I’d just like to know what is and isn’t expected to work. I’ve tried looking through release notes and looking for tech notes that describe what changed from iOS 7 to 8 and 8 to 9, but I haven’t been able to find anything that describes the CGColorSpace API changes. Does anyone know if there are any such documents?

2

There are 2 answers

1
Sumit Kumar Saha On

You can have a look at a open source library called little-CMS. It gives good results that you can integrate in your app.

https://github.com/mm2/Little-CMS

0
Slipp D. Thompson On

Your findings are correct— prior to iOS 9, ColorSync/CGColorSpace was not supported; all image assets were assumed to be in the device's sRGB color space (the documentation for CGColorSpace used to state “iOS does not support ColorSync, so all assets should be provided in the native device color space: sRGB”).

So even though CGColorSpace/CGColorSpaceRef existed in earlier releases, it didn't do anything until iOS 9.0.

So you have a few options:

  1. Only support iOS 9 or newer.
  2. Use proper color space rendering on iOS 9+; iOS 8- users will just get less accurate image color rendering.
  3. Use a 3rd-party library, like @SumitKumarSaha has suggested.

It's also worth noting that color-space-accurate rendering has become a bigger deal in the last year or so— the iPad Pro 9.7" (2016), iPad Pro 10.5" & 12.9" (2017), iPhone 7 & 7 Plus (2016), and newer models in those product lines all use the Display P3 wide color space (based on DCI P3).

More info at WWDC 2015 Session 510 - What's New in Core Image.