user2488826
user2488826

Reputation: 49

Android rsSetElementAt 4.2

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

Answers (2)

R. Jari
R. Jari

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

Stephen Hines
Stephen Hines

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

Related Questions