Creating a CGImage from an array of floats and byte order.

32 views
Skip to first unread message

thatsanice...@mac.com

unread,
Dec 6, 2011, 2:32:32 PM12/6/11
to quart...@lists.apple.com, Andy Lee
Hello,

I have an array of float values that I wanted to use to create a GCImage. The code looked roughly like this:

CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceGray();
CGContextRef bitmapContext;
bitmapContext = CGBitmapContextCreate(array,
_imageWidth,
_imageHeight,
bitsPerComponent,
_imageWidth * totalComponentsPerPixel * bytesPerComponent,
colorSpace,
kCGImageAlphaNone | kCGBitmapFloatComponents
);

All of the float values in array were previously scaled to [0,1]. CGBitmapContextCreate returned a valid object, but when displayed to screen the image was a 1-bit jumble. After poking around, I found that float values of 0.001 or less were white pixels, while larger values drew black pixels.

A fix was eventually found by changing

kCGImageAlphaNone | kCGBitmapFloatComponents

to

kCGImageAlphaNone | kCGBitmapFloatComponents | kCGBitmapByteOrder32Little

The Quartz documentation

http://developer.apple.com/library/IOs/#documentation/GraphicsImaging/Conceptual/drawingwithquartz2d/dq_context/dq_context.html#//apple_ref/doc/uid/TP30001066-CH203-BCIBHHBB

says that the original flag values are valid for a greyscale 32 bits per pixel image.

Why was the addition of the kCGBitmapByteOrder32Little flag needed? Is this something that should be updated in the documentation? Is this because I'm on an Intel processor, and should I be checking the endian-ness of the running machine whether I add the flag or not? Is there anything I should be aware of moving this to iOS (i.e. a non-Intel processor)?

Thanks for any help!

Cheers,
Demitri


_______________________________________________
Do not post admin requests to the list. They will be ignored.
Quartz-dev mailing list (Quart...@lists.apple.com)
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quartz-dev/quartz-dev-garchive-50095%40googlegroups.com

This email sent to quartz-dev-g...@googlegroups.com

David Duncan

unread,
Dec 6, 2011, 2:40:35 PM12/6/11
to thatsanice...@mac.com, quart...@lists.apple.com, Andy Lee
On Dec 6, 2011, at 11:32 AM, thatsanice...@mac.com wrote:

Why was the addition of the kCGBitmapByteOrder32Little flag needed? Is this something that should be updated in the documentation? Is this because I'm on an Intel processor, and should I be checking the endian-ness of the running machine whether I add the flag or not? Is there anything I should be aware of moving this to iOS (i.e. a non-Intel processor)?

As a bit of historical weirdness, Quartz defaults a non-existant endian flag as big-endian rather than host endian. Under 5- and 8-bpc formats, this generates bit-wise and pixel-size ordering that is the same (i.e. ARGB reads as ARGB regardless of if you read it 8 bits or 32 bits at a time). For 16 -and 32-bpc formats however, this leads to what you've seen. I'm not certain exactly why that choice was made, but it is something to be aware of when working with larger bpc formats.
--
David Duncan

Demitri Muna

unread,
Dec 6, 2011, 2:54:50 PM12/6/11
to quart...@lists.apple.com, Andy Lee
Hi David,

Thanks very much for the quick reply. It appears then that the (more) correct solution then is to specify:

kCGImageAlphaNone | kCGBitmapFloatComponents | kCGBitmapByteOrder32Host

Thanks!

Demitri

---

_______________________________________________

Reply all
Reply to author
Forward
0 new messages