In our app we use the following function for inverting a CGImageRef using vImage. The workflow is a obj-c version of the code in the AdjustingTheBrightnessAndContrastOfAnImage sample from Apple:
CGImageRef InvertImage( CGImageRef frameImageRef )
{
CGImageRef resultImage = nil;
CGBitmapInfo imgBitmapInfo = CGImageGetBitmapInfo( frameImageRef );
size_t img_bPC = CGImageGetBitsPerComponent( frameImageRef );
size_t img_bPP = CGImageGetBitsPerPixel( frameImageRef );
vImage_CGImageFormat invIFormat;
invIFormat.bitsPerComponent = img_bPC;
invIFormat.bitsPerPixel = img_bPP;
invIFormat.colorSpace = (img_bPP == 8) ? gDeviceGrayColorSpaceRef : gDeviceRGBColorSpaceRef;
invIFormat.bitmapInfo = imgBitmapInfo;
invIFormat.version = 0;
invIFormat.decode = 0;
invIFormat.renderingIntent = kCGRenderingIntentDefault;
vImage_Buffer sourceVImageBuffer;
vImage_Error viErr = vImageBuffer_InitWithCGImage( &sourceVImageBuffer, &invIFormat, nil, frameImageRef, kvImageNoFlags );
if (viErr == kvImageNoError)
{
vImage_Buffer destinationVImageBuffer;
viErr = vImageBuffer_Init( &destinationVImageBuffer, sourceVImageBuffer.height, sourceVImageBuffer.width, img_bPP, kvImageNoFlags );
if (viErr == kvImageNoError)
{
float linearCoeffs[2] = { -1.0, 1.0 };
float expoCoeffs[3] = { 1.0, 0.0, 0.0 };
float gamma = 0.0;
Pixel_8 boundary = 255;
viErr = vImagePiecewiseGamma_Planar8( &sourceVImageBuffer, &destinationVImageBuffer, expoCoeffs, gamma, linearCoeffs, boundary, kvImageNoFlags );
if (viErr == kvImageNoError)
{
CGImageRef newImgRef = vImageCreateCGImageFromBuffer( &destinationVImageBuffer, &invIFormat, nil, nil, kvImageNoFlags, &viErr );
if (viErr == kvImageNoError)
resultImage = newImgRef;
}
free( destinationVImageBuffer.data );
}
free( sourceVImageBuffer.data );
}
return resultImage;
}
The function works fine for 8-bit monochrome images. When I try it with 24-bit RGB images, although I get no errors from any of the calls, the output shows only the 1/3 of the image inverted as expected.
What am I missing? I suspect I might have to use a different function for 24-bit images (instead of the vImagePiecewiseGamma_Planar8) but I cannot find which one in the headers.
Thanks.