-1

In writting my Dictionary for a CG thumbnail creation, if I map the value directly to an int It works perfectly:

 NSDictionary* d = [NSDictionary dictionaryWithObjectsAndKeys:
                       (id)kCFBooleanTrue, kCGImageSourceShouldAllowFloat,
                       (id)kCFBooleanTrue, kCGImageSourceCreateThumbnailWithTransform,
                       (id)kCFBooleanTrue, kCGImageSourceCreateThumbnailFromImageAlways,
                       [NSNumber numberWithInt:56], kCGImageSourceThumbnailMaxPixelSize,
                       nil];
.
.
.
.
.
CGImageRef imref = CGImageSourceCreateThumbnailAtIndex(src, 0, (CFDictionaryRef)d);

Now I want to be able to change that value (56) to a property that I can change in my interface so I create an int in my header

my.h
int thumbSize;

//within my init method Iinitialize it:
        thumbSize = 56;
//then I change the reference in the dictionary:

    NSDictionary* d = [NSDictionary dictionaryWithObjectsAndKeys:
                       (id)kCFBooleanTrue, kCGImageSourceShouldAllowFloat,
                       (id)kCFBooleanTrue, kCGImageSourceCreateThumbnailWithTransform,
                       (id)kCFBooleanTrue, kCGImageSourceCreateThumbnailFromImageAlways,
                       [NSNumber numberWithInt:thumbSize], kCGImageSourceThumbnailMaxPixelSize,
                       nil];

If I do this, it crashes with the following error:

Mar 25 11:39:49 Charles-Romestants-MacBook.local PhotoMosaic[3583] : ImageIO: CGImageSourceCreateWithData data parameter is nil
Mar 25 11:39:49 Charles-Romestants-MacBook.local PhotoMosaic[3583] : ImageIO: CGImageSourceCreateImageAtIndex image source parameter is nil
2013-03-25 11:39:49.197 PhotoMosaic[3583:707] *** -[__NSArrayM insertObject:atIndex:]: object cannot be nil
2013-03-25 11:39:49.201 PhotoMosaic[3583:707] (
    0   CoreFoundation                      0x00007fff912ccb06 __exceptionPreprocess + 198
    1   libobjc.A.dylib                     0x00007fff8bc833f0 objc_exception_throw + 43
    2   CoreFoundation                      0x00007fff9127d27a -[__NSArrayM insertObject:atIndex:] + 282
    3   PhotoMosaic                         0x00000001000023bf -[BlendingView setMosaicImages:] + 1071
    4   PhotoMosaic                         0x0000000100003034 -[Controller createMosaic:] + 84
    5   AppKit                              0x00007fff8ec3d989 -[NSApplication sendAction:to:from:] + 342
    6   AppKit                              0x00007fff8ec3d7e7 -[NSControl sendAction:to:] + 85
    7   AppKit                              0x00007fff8ec3d71b -[NSCell _sendActionFrom:] + 138
    8   AppKit                              0x00007fff8ec3bc03 -[NSCell trackMouse:inRect:ofView:untilMouseUp:] + 1855
    9   AppKit                              0x00007fff8ec3b451 -[NSButtonCell trackMouse:inRect:ofView:untilMouseUp:] + 504
    10  AppKit                              0x00007fff8ec3abcc -[NSControl mouseDown:] + 820
    11  AppKit                              0x00007fff8ec3253e -[NSWindow sendEvent:] + 6853
    12  AppKit                              0x00007fff8ec2e674 -[NSApplication sendEvent:] + 5761
    13  AppKit                              0x00007fff8eb4424a -[NSApplication run] + 636
    14  AppKit                              0x00007fff8eae8c06 NSApplicationMain + 869
    15  PhotoMosaic                         0x0000000100001d52 main + 34
    16  PhotoMosaic                         0x0000000100001d24 start + 52
)

Why is this, I'm passing NSNumber +numberWithInt an int...

[EDIT] adding the whole method:

-(void)setMosaicImages:(NSMutableArray *)_mosaicImages
{
    NSLog(@"Entering here in setMosaicImages, we have %lu images",_mosaicImages.count);
    mosaicImages = _mosaicImages;
    CGImageSourceRef source;

    source = CGImageSourceCreateWithData((CFDataRef)[canvasImage TIFFRepresentation], NULL);
    CGImageRef image =  CGImageSourceCreateImageAtIndex(source, 0, NULL);
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(NULL,
                                             CGImageGetWidth(image), CGImageGetHeight(image),
                                             8, CGImageGetWidth(image) * 4,
                                             colorspace, kCGImageAlphaPremultipliedLast);
    CGColorSpaceRelease(colorspace);

    NSDictionary* d = [NSDictionary dictionaryWithObjectsAndKeys:
                       (id)kCFBooleanTrue, kCGImageSourceShouldAllowFloat,
                       (id)kCFBooleanTrue, kCGImageSourceCreateThumbnailWithTransform,
                       (id)kCFBooleanTrue, kCGImageSourceCreateThumbnailFromImageAlways,
                       [NSNumber numberWithInt:thumbSize], kCGImageSourceThumbnailMaxPixelSize,
                       nil];

//thumbSize is declared in.h and initialized in init method with a value of 56 (int thumbSize; then thumbSize = 56; if I change the parameter to literal 56 it works.    
//create NSMUTABLE array with thumbnails for each mosaic image
    mosaicCGThumbs = [[NSMutableArray alloc]initWithCapacity:mosaicCGThumbs.count];
    NSURL* url;
    for(int i=0; i<mosaicImages.count;i++)
    {
        url = [NSURL fileURLWithPath:[(myImageObject *)[mosaicImages objectAtIndex:i] getPath]];
        CGImageSourceRef src = CGImageSourceCreateWithURL((CFURLRef)url, NULL);
        CGImageRef imref = CGImageSourceCreateThumbnailAtIndex(src, 0, (CFDictionaryRef)d);
        [mosaicCGThumbs addObject:imref];
        CGImageRelease(imref);

    }
    CGRect r;
    CGImageRef thumbRef;
    int x_offset=0;
    int y_offset = 0;
    while(y_offset < CGImageGetHeight(image))
    {
        while (x_offset<CGImageGetWidth(image))
        {
            thumbRef = (CGImageRef)[mosaicCGThumbs objectAtIndex:arc4random() % mosaicCGThumbs.count];
            r = CGRectMake(x_offset, y_offset, CGImageGetWidth(thumbRef), CGImageGetHeight(thumbRef));
            CGContextSetBlendMode(ctx, kCGBlendModeCopy);
            CGContextDrawImage(ctx, r, thumbRef);

            x_offset+=CGImageGetWidth(thumbRef);
        }
        x_offset=0;
        y_offset+=56;
    }
    NSLog(@"Finished Drawing Mosaic BG");

    image = CGBitmapContextCreateImage(ctx);
    //
    //    CIImage* newImage = [[[CIImage alloc] initWithCGImage:image] autorelease];
    //    CGImageRelease(image);
    CGContextRelease(ctx);
    canvasImage = [[NSImage alloc] initWithCGImage:image size:NSZeroSize];
    mosaicPresent=YES;
    [self setNeedsDisplay:YES];

  }

Adding more information for debugging purposes:

I decided to see what is different with the created NSDictionary, so

I added the following code, and a breakpoint to inspect:

    NSDictionary* d = [NSDictionary dictionaryWithObjectsAndKeys:
                   (id)kCFBooleanTrue, kCGImageSourceShouldAllowFloat,
                   (id)kCFBooleanTrue, kCGImageSourceCreateThumbnailWithTransform,
                   (id)kCFBooleanTrue, kCGImageSourceCreateThumbnailFromImageAlways,
                   [NSNumber numberWithInt:thumbSize], kCGImageSourceThumbnailMaxPixelSize,
                   nil];

NSDictionary* d2 = [NSDictionary dictionaryWithObjectsAndKeys:
                   (id)kCFBooleanTrue, kCGImageSourceShouldAllowFloat,
                   (id)kCFBooleanTrue, kCGImageSourceCreateThumbnailWithTransform,
                   (id)kCFBooleanTrue, kCGImageSourceCreateThumbnailFromImageAlways,
                   [NSNumber numberWithInt:56], kCGImageSourceThumbnailMaxPixelSize,
                   nil];

Looking at it with the debugger I get this: (see how the two differ in the value,of pixel size for the thumbneail. will look more into this.

(gdb) po d
{
    kCGImageSourceCreateThumbnailFromImageAlways = 1;
    kCGImageSourceCreateThumbnailWithTransform = 1;
    kCGImageSourceShouldAllowFloat = 1;
    kCGImageSourceThumbnailMaxPixelSize = 0;
}
(gdb) po d2
{
    kCGImageSourceCreateThumbnailFromImageAlways = 1;
    kCGImageSourceCreateThumbnailWithTransform = 1;
    kCGImageSourceShouldAllowFloat = 1;
    kCGImageSourceThumbnailMaxPixelSize = 56;
}
cromestant
  • 652
  • 2
  • 10
  • 21
  • what about using `@(52)` is place of `[NSNumber numberWithInt:thumbSize]`? – Anoop Vaidya Mar 25 '13 at 16:55
  • 6
    The error you are getting doesn't appear to be explicitly from the code you posted, since the exception is actually happening in a call to an array method. Could you post the entire text of `BlendingView -setMosaicImages:` for us? – Seamus Campbell Mar 25 '13 at 16:56
  • 2
    The error is saying that the _source_ parameter is nil, nothing to do with the dictionary. –  Mar 25 '13 at 16:57
  • @SeamusCampbell: You have got BIG EYES :) – Anoop Vaidya Mar 25 '13 at 17:06
  • Actually @SeamusCampbell It is this, there is nothing else that changes, just that parameter. It is all happening within the setMosaicImages method. – cromestant Mar 25 '13 at 19:09
  • For reference I'm editing the OP to put the whole method. – cromestant Mar 25 '13 at 19:12
  • Your error has nothing to do with NSNumber: `[__NSArrayM insertObject:atIndex:]` – Hot Licks Mar 25 '13 at 19:56
  • You still haven't shown us your real source. – Hot Licks Mar 25 '13 at 19:59
  • @HotLicks I posted code on OP. There is nothing more to the code than this. The only change is changing the int directly to the variable reference. I know it is weird this is why im posting here. at that point it breaks, – cromestant Mar 25 '13 at 23:04
  • Where are you doing the insertObject? Set an exception breakpoint and then browse the stack to see where you are. – Hot Licks Mar 25 '13 at 23:33
  • Hi @HotLicks again I'm not "hiding"code, here is pastie with all the code on the blendingView. http://pastebin.com/D7ib8e2S it is basically the same, the inser is done on the [mosaicCGThumbs addObject:imref]; line – cromestant Mar 26 '13 at 02:53
  • If that's the case then imref is nil. Have you figured out why that is? – Hot Licks Mar 26 '13 at 03:19
  • Adding more information for help on the original POST – cromestant Mar 26 '13 at 23:42

2 Answers2

1

Are you certain that thumbSize is 56 when this code is executed? It seems unlikely.

I see in your pastebin that you have both an -init and an -initWithFrame: method. If you're initializing your object with -initWithFrame:, then your -init method is probably not being called, and hence not setting the value of thumbSize. It is an odd quirk (IMO; others may disagree) that the standard implementation of -initWithFrame: does not call -init.

Seamus Campbell
  • 17,816
  • 3
  • 52
  • 60
0

Ok, thank you for all your help : the error was even simpler than expected, the init method was notbeing called to initiate the variable, I had to put it in the initWithFrame:

- (id)init
{
    self = [super init];
    if (self) {
        // Initialization code here.
        mosaicPresent = NO;
    }

    return self;
}
- (id)initWithFrame:(NSRect)frameRect
{
    self = [super initWithFrame:frameRect];
    invalidateCanvas = YES;
    thumbSize = 56;

    return self;
}
cromestant
  • 652
  • 2
  • 10
  • 21