__kernel void finddots_2 (
int tileSizeBits,
int imgWidth,
int imgHeight,
int outTileSize,
int bg_limit,
int d,
__global uchar *input,
__global ushort *output
)
{
if (get_work_dim()!=2) return;
// Tile ID
uint tileID = (uint)(get_global_size(0)*get_global_id(1)+get_global_id(0));
#ifdef ECL
printf("tileID %d\n",tileID);
#endif
__global ushort * tileOutPtr=output+(tileID*outTileSize);
uint rowPitch=imgWidth;
// we start with 1 because we will store the length in the [0] component
uint valuesStored=1;
uint limitValuesStored=(outTileSize-sizeof(ushort))/2/sizeof(ushort)-1;
int x_begin=max((int)(get_global_id(0)<<tileSizeBits),(int)d);
int y_begin=max((int)(get_global_id(1)<<tileSizeBits),(int)d);
int x_end=min((int)((get_global_id(0)+1)<<tileSizeBits),(int)(imgWidth-d));
int y_end=min((int)((get_global_id(1)+1)<<tileSizeBits),(int)(imgHeight-d));
//printf("Range %d-%d,%d-%d\n",x_begin,x_end,y_begin,y_end);
uint tileMask=(1<<tileSizeBits)-1;
for (int y=y_begin;y<y_end;y++)
{
for (int x=x_begin;x<x_end;x++)
{
uchar xy0 = input[rowPitch*y+x];
bool candSearchOk=true;
if (xy0>bg_limit)
{
for (int yi=y-d;(yi<=y+d) && candSearchOk;yi++)
for (int xi=x-d;xi<=x+d;xi++)
{
uchar xyi=input[rowPitch*yi+xi];
if (xyi>xy0)
{
candSearchOk=false;
break;
}
else
if (xyi==xy0)
{
// depends where it is
if (!( // same pixel
((yi==y) && (xi==x)) ||
// its the direct bottom neighbor or
( (yi-y==1) && (xi==x) ) ||
// one of the three right neighbors
( ( (yi-y==-1) || (yi-y==0) || (yi-y==1) ) && ( xi-x==1) )
))
{
candSearchOk=false;
break;
}
}
}
if (candSearchOk)
{
// pixel found->refine and store
// useThisDot=true
// todo: refinement
int subPixelX=0;
int subPixelY=0;
#ifdef ECL
printf(" candidate at %d,%d \n",x,y);
#endif
tileOutPtr[valuesStored] = (ushort)(((x&tileMask)<<((sizeof(ushort)*8)-tileSizeBits))+subPixelX);
tileOutPtr[valuesStored+1] = (ushort)(((y&tileMask)<<((sizeof(ushort)*8)-tileSizeBits))+subPixelY);
valuesStored+=2;
if (valuesStored>=limitValuesStored)
{
x=x_end;
y=y_end;
break;
}
}
}
}
}
// store bytes stored by this work item
tileOutPtr[0] = (ushort)(valuesStored*sizeof(ushort));
}