ofImage and pixel format issue

Hi all,

I get a reference (from an ofImage) to the pixel data directly on a cpu thread, update the pixels and then call update on the GPU thread to create the texture. All is working fine, however, the Red and Blue colors are flipped for me.

The image is setup as OF_IMAGE_COLOR_ALPHA, and the (received) raw bitmap data has the following properties:

bpp = 32
depth = 32
bigEndian = 0 // is little endian
red, blue & green max is 255
red shift, green shift and blue shift are 16,8 and 0 respectively.
trueColor = true

I have verified that the ofImage created has an internal pixel format of RGBA. Below is data from ofPixels in the image:

06-24 18:36:25.914: V/ofxFramebuffer(2115): Image type: 2 // OF_IMAGE_COLOR_ALPHA
06-24 18:36:25.914: V/ofxFramebuffer(2115): Image bpp: 32
06-24 18:36:25.914: V/ofxFramebuffer(2115): Image bitsPerChannel: 8
06-24 18:36:25.919: V/ofxFramebuffer(2115): Image BytesPerPixel: 4
06-24 18:36:25.919: V/ofxFramebuffer(2115): Image PixelFormat: 4 // RGBA

Note: the bitmaps in my case are coming from a VNC server where we set the following PixelFormat:

06-24 18:36:25.699: V/ServerInfo(2115): ******* Logging Pixel Format ******
06-24 18:36:25.699: V/ServerInfo(2115): ss bbp: 32
06-24 18:36:25.699: V/ServerInfo(2115): ss depth: 32
06-24 18:36:25.699: V/ServerInfo(2115): ss bigEndian: 0
06-24 18:36:25.699: V/ServerInfo(2115): ss trueColor: 1
06-24 18:36:25.699: V/ServerInfo(2115): ss redMax: 255
06-24 18:36:25.699: V/ServerInfo(2115): ss greenMax: 255
06-24 18:36:25.699: V/ServerInfo(2115): ss blueMax: 255
06-24 18:36:25.699: V/ServerInfo(2115): ss redShift: 16
06-24 18:36:25.699: V/ServerInfo(2115): ss greenShift: 8
06-24 18:36:25.699: V/ServerInfo(2115): ss blueShift: 0
06-24 18:36:25.699: V/ServerInfo(2115): ******* End Pixel Format log ******

The copy process (from unsigned char * received) is identical to bitmaps that I receive from an RDP server (which is another part of the client), and the RDP buffer does not swap the red and blue.

The copy function is below for reference:

register int bpp = theBPP;
register int fbwidth = _vclient->drawBuffer->getWidth();
register int recth = somerect.h, rectw = somerect.w;

register unsigned char *fastsrc = src;
register char *fastdest = dest + bpp * somerect.y * fbwidth +  bpp * somerect.x;
register int rowsleft = recth, rowlength = bpp*rectw, fbmissingwidth = bpp*fbwidth;

while (rowsleft--)
{
	bcopy(fastsrc, fastdest, rowlength);
	fastsrc+=rowlength;
	fastdest+=fbmissingwidth;
}

dest is a pointer to the pixelData. src is the unsigned char array received from VNC.
drawBuffer is an instance of ofImage

Am I doing something obviously wrong?

Please note: this is on Android.

Thank you for any advice!

just set the pixel format in the ofPixels to OF_PIXELS_BGRA when allocating and it’ll show correctly when uploading to a texture

Thanks for quick response!

I am sorry but I am struggling with this – I can only set the image type (OF_IMAGE_COLOR_ALPHA, etc.) when allocating the image. Looking at what’s available in ofPixels.h, I don’t see a call to set the PixelFormat… I am obviously missing something very obvious, so apologies in advance, but how exactly do I do this?

My framebuffer extends ofImage, and the init call like this:

if (!pixAllocated) {
	clear();
	setUseTexture(true);
	allocate(framebufferWidth, framebufferHeight, imgType);
	pixAllocated = true;

	ofPixels tPixelData = getPixels();

	ofLogVerbose(_logTag) << "Image type: " << tPixelData.getImageType();
	ofLogVerbose(_logTag) << "Image bpp: " << tPixelData.getBitsPerPixel();
	ofLogVerbose(_logTag) << "Image bitsPerChannel: " << tPixelData.getBitsPerChannel();
	ofLogVerbose(_logTag) << "Image BytesPerPixel: " << tPixelData.getBytesPerPixel();
	ofLogVerbose(_logTag) << "Image PixelFormat: " << tPixelData.getPixelFormat();

	ofLogVerbose(_logTag) << "image allocated";

}

Thank you again!

oh i see, you need to use the nightly builds to be able to set the pixel format instead of the image type. otherwise you can try swapping r & b but that would be slower or uploading the data to the texture specifying the GL format like:

tex.loadData(pixels,GL_BGRA);

where pixels is an ofPixels

1 Like

Awesome! I’ll just sync with master.

Thank you again arturo – much appreciated!