CocoaDev

Edit AllPages

UPDATE: I found the problem. Since size_t is unsigned, the value of “-x” is only valid for x = 0 (which corresponds to the left-most column).

So in the provideImageData method, the line:

CGPoint drawpoint = CGPointMake(-x,height+y-h);

should be

CGPoint drawpoint = CGPointMake(-((float)x),(float)(height+y)-h);

With this, the code seems to work perfectly. I’m leaving this as is, in case anyone else has the same problem.

**The lesson here that you should always beware of types that wrap around primitives; you can’t always tell if they’re signed or not just by looking at them. With size_t, at least, it’s only logical for it to be unsigned (what would a negative sign even mean). But you might not guess with something like clock_t. A few clicks on “Jump to Definition” could save you a lot of headaches. This is also good to remember whenever something only works when a value is equal to zero. **

I am trying to implement the CIImageProvider informal protocol to facilitate “lazy” conversion of a CGLayer into a CIImage by specifying a tile size.

I have created a factory class, CILayerImage, which has the class method: +(CIImage *) imageWithCGLayer:(CGLayerRef)layer calibrated:(BOOL)calibratedColorSpace;

This uses a private helper class, CILayerProvider, which implements the CIImageProvider protocol to do the actual conversion. This class stores the layer and colorspace.

The relevant code from CILayerImage is:

+(CIImage *) imageWithCGLayer:(CGLayerRef)layer calibrated:(BOOL)calibratedColorSpace { CIImage * img = nil;

CGColorSpaceRef cs;
//set up colorspace
if(calibratedColorSpace) {
    cs = CGColorSpaceCreateWithName(kCGColorSpaceUserRGB);
} else {
    cs = CGColorSpaceCreateDeviceRGB();
}

//create a provider instance
CILayerProvider * prov = [[CILayerProvider alloc] initWithLayer:layer colorspace:cs];

if(prov) {
    CGSize size = CGLayerGetSize(layer);
    //Set up the CIImage to call the provider
    img = [CIImage imageWithImageProvider:prov size:size.width : size.height format:PIX_FORMAT colorSpace:cs
                                  options: [NSDictionary dictionaryWithObjectsAndKeys:
                                            [NSNumber numberWithInt:PROV_TILE_SIZE],  kCIImageProviderTileSize, nil]];

    [prov release];

}

if(cs)
    CGColorSpaceRelease(cs);
return img; }

And the relevant code from CILayerProvider is:

This compiles without any warnings and doesn’t log any errors at runtime.

The problem is that the resulting CIImage contains only the the tiles from the left-most column of the image. All other tiles are clear (as in black with alpha=0).

What I’ve done to explore this problem:

Especially in light of the fact that the problem still occurred with NSImage, I think I am either missing something fundamental, or this part of Core Image is completely broken. A Google search on this topic provided literally no help. Does anyone have any suggestions?

Failing that, does anyone know an efficient way to create a CIImage from a CGLayer that doesn’t immediately copy the entire layer? Would it be possible to extend CIImage to achieve the same result?