An app our company is developing is showing odd behavior and crashes under 10.6, but not under 10.5.

I've done some digging and figured out that a major contributor to the crash is the following routine:

(I've changed it slightly to get rid of unimportant details and make it more readable:


-(void) eraseImageRep: (NSBitmapImageRep*) theImageRep;
{
   NSSize  imageSize = [theImageRep size];
   unsigned long dataSize = [theImageRep bytesPerRow] * imageSize.height;
   void* theData = [theImageRep bitmapData];
   bzero(theData, dataSize);
}

Our app deals with indexed color images. We create a custom NSImage that contains an NSBitmapImageRep set up specifically to be non- planar, RGBA, 8 bits/channel. We then have code that converts back and forth between our indexed color document data and the byte format of our custom image rep.

The above call is used when we don't want to set context to the offscreen image and draw into it, but want to do a fast block erase.

After making this call in 10.6, the target NSImage stops drawing correctly, and and some future time a call to NSRectFill for this image crashes.

All the code to manipulate the image data of the image rep works perfectly, and if I replace the routine above with code that erases the image with code like this:

   [NSGraphicsContext setCurrentContext: offscreenImageContext];
   [[NSColor clearColor] setFill];
   NSRectFill(aRect);

It works perfectly.

I can certainly refactor our code to always clear our offscreen image (image rep) by setting context and doing Cocoa calls, but I want to understand why the routine above makes our app crash under 10.5 and not 10.6.

I thought we might be getting into trouble because we write to ALL the bytes in the image rep's bitmapData including padding bytes at the end of each row. I rewrote the routine above to only write to actual pixel bytes for each row and leave the padding bytes alone, but the app still crashes in 10.6.

That changed code looks like this: (again edited to simplify)

-(void) eraseImageRep: (NSBitmapImageRep*) theImageRep;
{
   NSSize          imageSize = [theImageRep size];
   void*           dataPtr;
   NSUInteger      index;
   NSUInteger      bytesPerRow = [theImageRep bytesPerRow];
   unsigned long       rowSize = size.width * 4;
   void*           theData = [theImageRep bitmapData];
   dataPtr =       theData;
for (index = 0; index < imageSize.height; index++)
   {
       memset(dataPtr, 0, rowSize);
       dataPtr += bytesPerRow;
   }
}

Interestingly, our app calls the above routine in several places, and it is only one of the calls that causes us problems. I have not been able to figure out what it is about this particular use of the erase routine that causes the problem.





The code that creates our NSImage and image rep looks like this:

       tempDisplayImageRecord.theImageRep =
       [[[NSBitmapImageRep alloc]
         initWithBitmapDataPlanes: NULL
         pixelsWide:               size.width
         pixelsHigh:               size.height
         bitsPerSample:            8                       //1 byte for R, G, 
B, and A
         samplesPerPixel:          4                       //Specify RGBA
         hasAlpha:                 YES                     //Ask for an alpha 
channel
         isPlanar:                 NO                      //RGBA data is mixed 
together for each pixel.
         //If planar, there are separate buffers for r, g, b, and a values
colorSpaceName: NSDeviceRGBColorSpace //Use device color. This avoids color profile matching
         bytesPerRow:              0                       //Let the system 
decide how many bytes/row.
         //This way it can add padding so rows begin on memory boundaries
bitsPerPixel: 0] autorelease]; //Let the system calculate this (but it's 32 bits/pixel) if (!tempDisplayImageRecord.theImageRep) return -1; //>>>>>>ERROR! <<<<<< Report to user!!!! [(tempDisplayImageRecord.theImage = [[TestImage allocWithZone:[self zone]] initWithSize:size]) addRepresentation:tempDisplayImageRecord.theImageRep];

if (!tempDisplayImageRecord.theImage) return -1; //>>>>>>ERROR! <<<<<< Report to user!!!! tempDisplayImageRecord.theContext = [NSGraphicsContext graphicsContextWithBitmapImageRep: tempDisplayImageRecord.theImageRep]; if (!tempDisplayImageRecord.theContext) return -1; //>>>>>>ERROR! <<<<<< Report to user!!!!



Does anybody out there have any idea what's going on, and why we are seeing different behavior from 10.5 and 10.6? This has me stumped.



Regards,

Duncan Champney
WareTo
_______________________________________________

Cocoa-dev mailing list (Cocoa-dev@lists.apple.com)

Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com

Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/cocoa-dev/archive%40mail-archive.com

This email sent to arch...@mail-archive.com

Reply via email to