EDIT: I worked around this issue but to rephrase my question - is it possible to create the CVPixelBuffer to match the CGImage? For example I would like to have 16 bits per component instead of 8.
As the title says. For example, when I NSLog my buffer it has 4544 bytes per row. But when I NSLog the actual CGImage it has 9000. This is the logs:
buffer: <CVPixelBuffer 0x282b8b020 width=1125 height=2436 bytesPerRow=4544 pixelFormat=BGRA iosurface=0x0 attributes={ PixelFormatDescription = {
BitsPerBlock = 32;
BitsPerComponent = 8;
BlackBlock = {length = 4, bytes = 0x000000ff};
CGBitmapContextCompatibility = 1;
CGBitmapInfo = 8196;
CGImageCompatibility = 1;
ComponentRange = FullRange;
ContainsAlpha = 1;
ContainsGrayscale = 0;
ContainsRGB = 1;
ContainsYCbCr = 0;
FillExtendedPixelsCallback = {length = 24, bytes = 0x00000000000000008c3c1da7010000000000000000000000};
IOSurfaceCoreAnimationCompatibility = 1;
IOSurfaceOpenGLESFBOCompatibility = 1;
IOSurfaceOpenGLESTextureCompatibility = 1;
OpenGLESCompatibility = 1;
PixelFormat = 1111970369;
};
} propagatedAttachments={
} nonPropagatedAttachments={
}>
And the image
image: <CGImage 0x1044625d0> (IP) <<CGColorSpace 0x283e9ea60> (kCGColorSpaceICCBased; kCGColorSpaceModelRGB; Display P3)>
width = 1125, height = 2436, bpc = 16, bpp = 64, row bytes = 9000
kCGImageAlphaNoneSkipLast | kCGImageByteOrder16Little | kCGImagePixelFormatPacked
is mask? No, has masking color? No, has soft mask? No, has matte? No, should interpolate? Yes
This is the code I use
CGImageRef cgImageRef = [image CGImage];
CGImageRetain(cgImageRef);
CVPixelBufferRef pixelBuffer = NULL;
size_t w = CGImageGetWidth(cgImageRef);
size_t h = CGImageGetHeight(cgImageRef);
CGDataProviderRef x = CGImageGetDataProvider(cgImageRef);
CGDataProviderRetain(x);
CFDataRef da = CGDataProviderCopyData(x);
CFIndex len = CFDataGetLength(da);
const uint8_t* src = CFDataGetBytePtr(da);
CVPixelBufferCreate(kCFAllocatorDefault,
w,
h,
kCVPixelFormatType_32BGRA,
nil,
&pixelBuffer);
CVPixelBufferLockBaseAddress( pixelBuffer, 0 );
void* base = CVPixelBufferGetBaseAddress(pixelBuffer);
SNLog(@"buffer: %@", pixelBuffer);
SNLog(@"image: %@", cgImageRef);
I am later trying to go through the CGImage address and manually copy the bytes into the destination pixel buffer. But it crashes and I assume it is because I am at some point trying to read from "after" the actual image.
I guess my initial question was not exactly clear, or perhaps I should have rephrased it slightly. The problem is more like - I would like to create my buffer to match the image - with the same amount of bytes/bits per component.
I worked around this by looping through the buffer and picking individually bytes I want from the image. Basically ignoring some bits of each pixel.
In the end the image looks fine still, I suspect the increased amount of bits is used for better quality on more capable screens. Although I am not sure.