Question

I'm trying to create an UIImage test pattern for an iOS 5.1 device. The target UIImageView is 320x240 in size, but I was trying to create a 160x120 UIImage test pattern (future, non-test pattern images will be this size). I wanted the top half of the box to be blue and the bottom half to be red, but I get what looks like uninitialized memory corrupting the bottom of the image. The code is as follows:

int width = 160;
int height = 120;
unsigned int testData[width * height];
for(int k = 0; k < (width * height) / 2; k++)
    testData[k] = 0xFF0000FF;   // BGRA (Blue)
for(int k = (width * height) / 2; k < width * height; k++)
    testData[k] = 0x0000FFFF;   // BGRA (Red)

int bitsPerComponent = 8;
int bitsPerPixel = 32;
int bytesPerRow = 4 * width;
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, &testData, (width * height * 4), NULL);
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();      
CGBitmapInfo bitmapInfo = kCGImageAlphaNoneSkipFirst;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;

CGImageRef imageRef = CGImageCreate(width, height, bitsPerComponent, bitsPerPixel, bytesPerRow, 
                                    colorSpaceRef, bitmapInfo, provider, NULL, NO,renderingIntent);

UIImage *myTestImage = [UIImage imageWithCGImage:imageRef];

This should look like another example on Stack Overflow. Anyway, I found that as I decrease the size of the test pattern the "corrupt" portion of the image increases. What is also strange is that I see lines of red in the "corrupt" portion, so it doesn't appear that I'm just messing up the sizes of components. What am I missing? It feels like something in the provider, but I don't see it.

Thanks!

Added screenshots. Here is what it looks like with kCGImageAlphaNoneSkipFirst set:

AlphaSkipFirst

And here is what it looks like with kCGImageAlphaFirst:

enter image description here

Was it helpful?

Solution

Your pixel data is in an automatic variable, so it's stored on the stack:

unsigned int testData[width * height];

You must be returning from the function where this data is declared. That makes the function's stack frame get popped and reused by other functions, which overwrites the data.

Your image, however, still refers to that pixel data at the same address on the stack. (CGDataProviderCreateWithData doesn't copy the data, it just refers to it.)

To fix: use malloc or CFMutableData or NSMutableData to allocate space for your pixel data on the heap.

OTHER TIPS

Your image includes alpha which you then tell the system to ignore by skipping the most significant bits (i.e. the "B" portion of your image). Try setting it to kCGImageAlphaPremultipliedLast instead.

EDIT:

Now that I remember endianness, I realize that the program is probably reading your values in backwards, so what you might actually want is kCGImageAlphaPremultipliedFirst

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top