Dear Alex,

CoreImage compiles all kernels internally to one, and will try to be the most efficient by processing the less pixels possible. If you crop your image at the end to (0., 0., 100., 1.), why would CoreImage upload your whole input image? It will actually only upload the region (0., 0., 100., 1.) of that image, and you will get a "wrong" result as you "makeStrip" kernel requires the whole input image to generate a (0., 0., 100., 1.) image.

ROI are the way you tell a kernel that it needs a different region in the input image (ROI) than the region which is processed at the output (DOD). For consistent results you must define a ROI whenever for an output pixel (x.y) you are fetching pixel in the input image different from (x,y).

For your particular issue, a easy fix is to pass as the userInfo of the ROI function your DOD and make the ROI function simply return that DOD. This means that you need the following changes:

-------------
//First, add at the beginning of script:

function myROIFunction (samplerIndex, dstRect, info)
{
        return info;
}

makeStrip.ROIHandler = myROIFunction;

//Then, pass dodRect as userInfo for makeStrip call:

imageStrip = makeStrip.apply(dodRect, dodRect, imagePixellated, CellWidth, CellHeight, CellNum, Cols);
-------------

However this will not work for big images that requires tiling as dodRect will be bigger than maximum texture size of the GPU. In that case the ROI function will be called multiple times to process tiles of your dodRect, which will be given in the dstRect argument. In that case you must return the region of the input image needed to process only the dstRect: you'll use the info = dodRect argument and will return the appropriate subregion.

Marc, <rdar://5558266> is a different issue.

Kevin

On Dec 12, 2007, at 5:05 AM, Alex Drinkwater wrote:

// KERNEL

// SUPPORTING FUNCTIONS

// Used by makeStrip (returns coord of pixel to be
sampled)
vec2 sampleHere(vec2 xy, float cellWidth, float
cellHeight, float cols)
{
        // Calculate Row and Column for current iteration
        float rowNum = ceil(xy.x / cols);
        float colNum = xy.x - ((rowNum - 1.0) * cols);
        // Calculate position of pixel to copy
        xy.x = colNum * cellWidth;
        xy.y = rowNum * cellHeight;
        
        // Return coord for sampler
        return xy;
}

// MAIN KERNEL FUNCTIONS (RETURN IMAGES)

// Pixellates image with exact dimensions for pixel
tiles' width and height
kernel vec4 xy_pixellate(sampler Image, float
CellWidth, float CellHeight)
{
        // Current pixel location
        vec2 xy = destCoord();
        // Left and right of tile
        float x1 = floor(xy.x / CellWidth) * CellWidth;
        float x2 = (ceil(xy.x / CellWidth)) * CellWidth;
        // Top and bottom of tile
        float y1 = (floor(xy.y / CellHeight) * CellHeight);
        float y2 = (ceil(xy.y / CellHeight)) * CellHeight;
        
        // Average left and right pixels
        vec4 avgX = (sample(Image, samplerTransform(Image,
vec2(x1, y1)))+(sample(Image,
samplerTransform(Image,
vec2(x2, y1))))) / 2.0;
        
        // Average top and bottom pixels
        vec4 avgY = (sample(Image, samplerTransform(Image,
vec2(x1, y1)))+(sample(Image,
samplerTransform(Image,
vec2(x1, y2))))) / 2.0;
        // Centre pixel
        vec4 avgC = sample(Image, samplerTransform(Image,
vec2(x1+(CellWidth/2.0), y2+(CellHeight/2.0))));
        // Average the averages + centre
        vec4 outPix = (avgX+avgY+avgC) / 3.0;
        
        // Output
        return outPix;
}

// Creates 1-pixel-high strip from input image
kernel vec4 makeStrip(sampler Image, float
CellWidth,
float CellHeight, float CellNum, float Cols)
{
        // Current pixel position
        vec2 xy = destCoord();
        vec2 samplePos = (xy.x > CellNum) ? vec2(0.0,0.0) :
(xy.y > 10.0) ? vec2(0.0,0.0) : sampleHere(xy,
CellWidth, CellHeight, Cols);
        
        // Output
        return sample(Image, samplerTransform(Image,
vec2(samplePos)));
}


// JAVASCRIPT

function __image main(__image Image, __number Rows,
__number Cols)
{
        // CREATE CONTROL VALUES
        
        // Input image dimensions
        var Width = Image.extent.width;
        var Height = Image.extent.height;
        // Dimensions of Pixellation cells
        var CellWidth = Width / (Math.ceil(Rows));
        var CellHeight = Height / (Math.ceil(Cols));
        // Total number of cells
        var CellNum = Rows * Cols;
        // DOD rect
        var dodRect = new Vec(0.0, 0.0, Width, Height);
        
        
        // IMAGE OPERATIONS
        
        // Pixellate image
        imagePixellated = xy_pixellate.apply(dodRect, null,
Image, CellWidth, CellHeight);
        // Create strip
        imageStrip = makeStrip.apply(dodRect, null,
imagePixellated, CellWidth, CellHeight, CellNum,
Cols);
        // Crop
        imageCropped = Filter.Crop(imageStrip, new Vec(0.0,
0.0, CellNum, 1.0));
        // Output
        return imageCropped;
}



Anything obvious jump out as still being wrong?

Cheers again for your advice,

Alex

--- Kevin Quennesson <[EMAIL PROTECTED]> wrote:

Sure,

The ROI is the rectangle in the source image that
is
needed by the
kernel to process pixel in a given destination
rectangle (dstRect)

Here's a example of simple subsampling by 2 of an
image:

//KERNEL:
kernel vec4 susbample(sampler image)
{
        vec2 xy = destCoord();
        xy = (xy - vec2(0.5,0.5)) * 2. + vec2(0.5,0.5);
//
Pixels are
sampled at half coordinates.
        return sample(image, samplerTransform(image,
xy));
}

//JavaScript:

function myROIFunction(samplerIndex, dstRect,
info)
{
        var roiRect = new Vec(dstRect.x*2., dstRect.y*2.,
dstRect.width*2.,
dstRect.height*2.); //ROI is twice bigger than
dstRect
        return roiRect;
}

susbample.ROIHandler = myROIFunction;

function __image main(__image image) {
        var dodRect = new Vec(image.extent.x/2.,
image.extent.y/2.,
image.extent.width/2., image.extent.height/2.);
//DOD of resulting
image is twice smaller that image.extent
        return susbample.apply(dodRect, null, image);
}

On Dec 11, 2007, at 12:48 AM, Alex Drinkwater
wrote:

On 11 Dec 2007, at 03:32, Kevin Quennesson
wrote:

Hi,

When your kernel reads pixel at a location
different from the


-----------
Kevin Quennesson
Quartz Composer Team
Apple Inc.




 _______________________________________________
Do not post admin requests to the list. They will be ignored.
Quartzcomposer-dev mailing list      ([email protected])
Help/Unsubscribe/Update your Subscription:
http://lists.apple.com/mailman/options/quartzcomposer-dev/archive%40mail-archive.com

This email sent to [EMAIL PROTECTED]

Reply via email to