Reputation: 49
I am trying to find the min and max pixel values of my camera image using my renderscript. My render script file tries to call rsSetElementAt but I get the following warning:
C:\Users\tec\workspace\RSTestProject\src\com\myrs.rs:59:9: warning: implicit declaration of function 'rsSetElementAt_uint' is invalid in C99
Since it was a warning I went ahead and ran the rs. The program crashed with the following error:
E/RenderScript: ScriptC sym lookup failed for rsSetElementAt_uint
WHAT'S Up with this? Thanks
#pragma version(1)
#pragma rs java_package_name(com.techleadz.rstestproject)
rs_allocation gIn;
rs_allocation gOut;
rs_allocation gMin; // min matrix
rs_allocation gMax; // max matrix
bool reduce_constraints;
bool reset_constraints;
rs_script gScript;
//const uchar4 *gPixels;
int mode;
// this is invoked automatically
void init() {
rsDebug( "initRS:", "mode" );
}
void filter() {
rsDebug( "Number of Rows:", "mode" );
rsForEach( gScript, gIn, gOut );
}
void RegisterPixels( const uchar4 *v_in, uchar4 *v_out, uint32_t column, uint32_t row ) {
unsigned int input = (int)v_in;
rsDebug( "Number of Rows:", rsAllocationGetDimX(gIn) );
rsDebug("Printing out a Point", input);
// see if this pixel exceeds the min and max
// get an entire row if possible ????
const uint *minRow = rsGetElementAt( gMin, row, column );
const uint *maxRow = rsGetElementAt( gMax, row, column );
uint newMinRow, newMaxRow;
unsigned char minRowRed, minRowGreen, minRowBlue;
unsigned char maxRowRed, maxRowGreen, maxRowBlue;
minRowRed = *minRow&0xff;
minRowGreen = *minRow&0xff00 >> 8;
minRowBlue = *minRow&0xff0000 >> 16;
maxRowRed = *maxRow&0xff;
maxRowGreen = *maxRow&0xff00 >> 8;
maxRowBlue = *maxRow&0xff0000 >> 16;
// if reduce_constraints then do it first. This will force the constraints
if( mode == 1 ) // gReduce_constraints == true ) {
{
// to recalculate as the sun rises or sets
// go through the entire row
minRowRed += 1; minRowGreen += 1; minRowBlue += 1;
maxRowRed -= 1; maxRowGreen -= 1; maxRowBlue -= 1;
// recombined RGB
newMinRow = minRowRed & (minRowGreen<<8) & (minRowBlue<<16);
newMaxRow = maxRowRed & (maxRowGreen<<8) & (maxRowBlue<<16);
rsSetElementAt_uint( gMin, newMinRow, row, column );
//rsSetElementAt_int( gMin, 0, 0 );
//rsSetElementAt_uint( gMax, newMaxRow, row, column );
}
unsigned char inputRed = input&0xff;
unsigned char inputGreen = (input&0xff00)>>8;
unsigned char inputBlue = (input&0xff0000)>>16;
// first see if this pixel is the wrong color
// Brown deer are within a range of RGB values
if( ( inputRed < 40 ) && ( inputRed > 218 ) ) return;
if( ( inputGreen < 40 ) && ( inputGreen > 177 ) ) return;
if( ( inputBlue < 40 ) && ( inputBlue > 167 ) ) return;
if( ( inputRed > minRowRed ) && ( inputRed < maxRowRed ) ) {
if( ( inputGreen > minRowGreen ) && ( inputGreen < maxRowGreen ) ) {
if( ( inputBlue > minRowBlue ) && ( inputBlue < maxRowBlue ) ) {
newMaxRow = newMaxRow | 0xff000000;
v_out = newMaxRow;
// place the hit in the upper byte
//rsSetElementAt_int( gMax, newMaxRow, row, column );
}
}
}
return;
}
// the following RenderScript will find the min and max pixel
//void __attribute__((kernel))LearnArea( uint row ) {
void LearnArea( const uchar4 *v_in, uchar4 *v_out, uint32_t column, uint32_t row) {
const unsigned int *lmin;
const unsigned int *lmax;
unsigned int newlmin;
unsigned int newlmax;
bool changed = false;
rsDebug( "LearnArea:", rsAllocationGetDimX(gIn) );
unsigned int input = (int)v_in;
unsigned char inputRed = input&0xff;
unsigned char inputGreen = (input&0xff00)>>8;
unsigned char inputBlue = (input&0xff0000)>>16;
if( reset_constraints == true) {
rsSetElementAt_int( gMin, 255, row, column );
//rsSetElementAt_int( gMax, 0, row, column );
}
else {
lmin = rsGetElementAt( gMin, row, column );
lmax = rsGetElementAt( gMax, row, column );
unsigned char minRed = *lmin&0xff;
unsigned char minGreen = (*lmin&0xff00)>>8;
unsigned char minBlue = (*lmin&0xff0000)>>16;
// see if the current pixel is less than the min
changed = false;
if( inputRed < minRed ) {
minRed = inputRed;// red
changed = true;
}
if( inputGreen < minGreen ) {
minGreen = inputGreen; // green
changed = true;
}
if( inputBlue < minBlue ) {
minBlue = inputBlue;// blue
changed = true;
}
if( changed == true ) {
newlmin = minRed & (minGreen<<8) & (minBlue<<16);
rsSetElementAt_int( gMin, newlmin, row, column );
}
unsigned char maxRed = *lmax&0xff;
unsigned char maxGreen = (*lmax&0xff00)>>8;
unsigned char maxBlue = (*lmax&0xff0000)>>16;
changed = false;
// see if the current pixel is less than the min
if( inputRed < maxRed ) {
maxRed = inputRed;// red
changed = true;
}
if( inputGreen < maxGreen ) {
maxGreen = inputGreen;// green
changed = true;
}
if( inputBlue < maxBlue ) {
maxBlue = inputBlue;// blue
changed = true;
}
if( changed == true ) {
newlmax = maxRed & (maxGreen<<8) & (maxBlue<<16);
v_out =
rsSetElementAt_int( gMax, newlmax, row, column );
}
}
return;
}
/*
// use a radius to decide if a large area has exceed the thresholds
//void __attribute__((kernel))FindHits( uint rowCenter, uint cellSize, uint threshold )
void FindHits( uint rowCenter, uint cellSize, uint threshold )
{
uint columnSum=0; // sum of the current sub column
uint sums[cellSize]; // sum of a small column
uint runningSum=0; // the sum of the cells_size x cell_size
uint halfCellSize = cellSize/2;
uint currentColumn=0;
rsDebug( "FindHits:", rsAllocationGetDimX(gIn) ); // rsUptimeMillis()
uint rowOffset = rowCenter - halfCellSize; // shortcut from doing this every iteration
for( uint i=0; i < gWidth; i ++ ) {
columnSum = 0;
for( uint j=0; j < cellSize; j ++ ) {
columnSum += rsElementGet_int( gHits, rowOffset + j, i );
}
if( i < cellSize ) {
runningSum += columnSum;
}
else {
// always subtract off the trailing column and add the current column
runningSum = runningSum + columnSum - sums[currentColumn];
if( runningSum > threshold ) {
gMovementPresentRow = rowCenter;
gMovementPresentColumn = i;
return;
}
sums[currentColumn] = columnSum;
}
currentColumn ++;
if( currentColumn > cellSize ) currentColumn = 0;
}
return;
}
*/
void root( const uchar4 *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y ) // v_out is the min/max
{
rsDebug( "root:", "mode is" );
if( mode == 0 )
{
RegisterPixels( v_in, v_out, x, y );
rsDebug( "root:", "mode is 0" );
}
else if( mode == 1 )
{
//LeanArea( v_in, v_out );
rsDebug( "root:", "mode is 1" );
}
else if( mode == 2 )
{
rsDebug( "root:", "mode is 2" );
//FindHits( v_in, v_out );
}
else
rsDebug( "root:", "mode is 3" );
Upvotes: 1
Views: 1019
Reputation: 305
The problem is of the renderScriptTargetApi. In order to use rsSetElementAt keep your renderScriptTargetApi to 18. Also, if problem persists, check all the parameters required for rsSetElementAt are having the exact datatype as provided in the documentation. In your case typecast row and column as rsSetElementAt_int( gMax, newlmax, (uint32_t)row, (uint32_t)column );
Upvotes: 2
Reputation: 2622
rsSetElementAt() and rsSetElementAt_*() are only available starting in target API 18. Since API 18 is not actually available on any Android device yet, you are not going to be able to properly execute this code until the next version of Android is released. I am not sure how you managed to get the function actually declared enough to compile (perhaps this is using the latest SDK?), but it is always going to fail to load on the device for now.
Upvotes: 3