CGImage crashing simulator

Discussion in 'iOS Programming' started by RossOliver, Apr 27, 2008.

  1. macrumors regular

    Nov 6, 2006

    I'm having problems with a CGImage. I have overridden a UIView allowing me to initialize it with an 'underlay' image that originally fills the view. I can then set the overlayImage instance variable to a CGImage and it is draw on top of the 'underlay' image using the drawRect method:

    -( id )initWithItemUnderlay:( UIImage * )itemUnderlay frame:( CGRect )frame
        if( self = [super initWithFrame:frame] )
    		UIImageView *imageView = [[UIImageView alloc] initWithImage: itemUnderlay];
    		[self addSubview:imageView];
    		[imageView release];
    		overlayImage = NO;
        return self;
    -( void )setOverlayImage:( CGImageRef )newOverlayImage
    	overlayImage = newOverlayImage;
    -( CGImageRef )overlayImage
    	return overlayImage;
    -( void )drawRect:( CGRect )rect
    	if( overlayImage )
    		CGContextRef context = UIGraphicsGetCurrentContext(); 
    		CGContextDrawImage( context, rect, overlayImage );
    This view is created with an underlay/overlay image in a different class:

    itemView = [[ItemView alloc] initWithItemUnderlay:defaultItemUnderlay 
    [itemView setOverlayImage:[UIImage imageNamed:@"MyImage.png"].CGImage];
    [customTableView addSubview:itemView];
    So far this works fine - the underlay image is set and the overlay image is draw on top of it. I can then change the overlayImage using setOverlayImage and it redraws the overlay image as I would want.

    However, the simulator crashes if I use an image I gather from the web. I have an Item class that can hold a CGImageRef. An instance of the Item class is created and the image is set to an image gathered from the web:

    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    [item setImage:[UIImage imageWithData:imageData].CGImage];
    This item class gets returned to the class that originally set the overlay/underlay images. I know the image gathered is correct as I have displayed it as a UIImage before. However, if I now set the CGImage from the Item class as the overlay image the simulator crashes:

    [itemView setOverlayImage:[item image]]; // doesn't work
    // [itemView setOverlayImage:[UIImage imageNamed:@"MyImage.png"].CGImage] // does work.
    [itemView setNeedsDisplay];
    Is there something special required to retain a CGImage in an instance variable? I've been pulling my hair out over this for days - if anyone can help I would really appreciate it...

    In case it helps, this is a chunk of the report from the crash:

    Process:         MyApp [14803]
    Path:            /Users/Ross/Library/Application Support/iPhone Simulator/User/Applications/583EAA3F-4E73-4D8C-8928-ACCC6837C773/
    Identifier:      MyApp
    Version:         ??? (???)
    Code Type:       X86 (Native)
    Parent Process:  launchd [89]
    Date/Time:       2008-04-28 02:05:18.256 +0100
    OS Version:      Mac OS X 10.5.2 (9C7010)
    Report Version:  6
    Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
    Exception Codes: KERN_INVALID_ADDRESS at 0x0000000044b2e002
    Crashed Thread:  0
    Thread 0 Crashed:
    0        	0x31062bd6 decode_byte_8bpc_3 + 70
    1        	0x30fcb27e decode_data + 4614
    2        	0x30fc9f54 img_decode_read + 1641
    3        	0x3102fad5 img_interpolate_read + 656
    4        	0x30fc7351 img_data_lock + 4996
    5        	0x30fc55ef CGSImageDataLock + 168
    6   libRIP.A.dylib                	0x00289160 ripc_AcquireImage + 3116
    7   libRIP.A.dylib                	0x002784a0 ripc_DrawImage + 3652
    8        	0x30fc53d5 CGContextDrawImage + 397
    9   MyApp                        	0x000060f7 -[ItemView drawRect:] + 73 (ItemView.m:42)
    10  UIKit                         	0x30b4a820 -[UIView(CALayerDelegate) drawLayer:inContext:] + 452
    11  QuartzCore                    	0x32022512 -[CALayer drawInContext:] + 65
    12  QuartzCore                    	0x320224b9 backing_callback + 69
    13  QuartzCore                    	0x320220cd CABackingStoreUpdate + 1938
    14  QuartzCore                    	0x3202176e -[CALayer _display] + 896
    15  QuartzCore                    	0x32015c32 CALayerDisplayIfNeeded + 178
    16  QuartzCore                    	0x32013f77 CAContextCommitTransaction + 191
    17  QuartzCore                    	0x32013c66 CATransactionCommit + 205
    18      	0x967e29c2 __CFRunLoopDoObservers + 466
    19      	0x967e3c60 CFRunLoopRunSpecific + 656
    20      	0x967e4d18 CFRunLoopRunInMode + 88
    21  GraphicsServices              	0x31670e4a GSEventRunModal + 217
    22  GraphicsServices              	0x31670f0f GSEventRun + 115
    23  UIKit                         	0x30b2679b -[UIApplication _run] + 441
    24  UIKit                         	0x30b30de0 UIApplicationMain + 1224
    25  MyApp                        	0x00001ee4 main + 102 (main.m:14)
    26  MyApp                        	0x00001e52 start + 54
    Thanks for your time.
  2. thread starter macrumors regular

    Nov 6, 2006
    I've narrowed the problem down to these few lines:

    NSURL *imageURL = [NSURL URLWithString:[[query objectAtIndex:0] stringValue]];
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    //[item setImage:[UIImage imageWithData:imageData].CGImage];
    [item setImage:[UIImage imageNamed:@"test.jpg"].CGImage];
    By replacing the commented out line with the line using an image in my application it works perfectly. Is there a step I have missed out when converting the imageData to a CGImage?

    As I said in my other post, the image itself works correctly when I just make it into a UIImage from the NSURL instead of CGImage...

    Another odd thing I noticed was that the image is flipped upside down before it's drawn in drawRect :confused:



    Managed to get the image the correct way up using this useful code snippet:

    	CGContextTranslateCTM( context, 0, CGRectGetMaxY( rect ) );
    	CGContextScaleCTM( context, 1.0, -1.0 );
    	rect = CGRectOffset( rect, 0, -rect.origin.y );
  3. macrumors newbie

    Sep 16, 2003
    did you find a fix?

    I'm also running into random crashes when doing exactly your senario - compositing two images, one of which was grabbed from the web. It looks like the issue is in UIGraphicsGetCurrentContext();

    I f I just use local UIImages = no problems...
  4. macrumors newbie

    Jan 31, 2008
    Try to call it from the main thread:

    [self.imageViewer performSelectorOnMainThread:mad:selector(setImage:) withObject:(id)cgImage waitUntilDone:NO];
  5. macrumors regular

    Sep 11, 2008
    In the code above (1st post) you never retain it. I suppose it all works nice with -imageNamed: because those images tend to stick around for a long time.
  6. macrumors 68030


    Sep 2, 2008
    This thread is over two years old. They probably figured it out by now.
  7. macrumors regular

    Sep 11, 2008
    Ups, you are right. I wasn't paying attention to all the dates. The guy in front of me had a fresh time on his post and I probably assumed all was fine.

    Now when I looked at this thread more carefully I have noticed that original message from 2008 resurfaced twice so far. First time after 8 months and now after more than two years. Second interesting thing is the label on yoavhacohen:

    Joined in 2008, macrumors newbie.
  8. macrumors 604


    Nov 26, 2007
    Member titles are mostly based on the number of posts a member has made. They probably just haven't posted much since joining the forums.

Share This Page