void Transform::twist( RawTile& rawtile, const vector< vector<float> >& matrix ){

  unsigned long np = rawtile.width * rawtile.height;

  // Create temporary buffer for our calculated values
  float* pixel = new float[rawtile.channels];

  // Calculate the number of columns - limit to our number of channels if necessary
  unsigned int ncols = (matrix.size()>(unsigned int)rawtile.channels) ? rawtile.channels : matrix.size();
  unsigned int* nrows = new unsigned int[ncols];

  // Pre-calculate the size of each row
  for( unsigned int i=0; i<ncols; i++ ){
    nrows[i] = (matrix[i].size()>(unsigned int)rawtile.channels) ? rawtile.channels : matrix[i].size();
  }


  for( unsigned long i=0; i<np; i++ ){

    unsigned long n = i*rawtile.channels;

    // Calculate value for each channel
    for( unsigned int k=0; k<ncols; k++ ){

      // Zero our pixel buffer
      pixel[k] = 0.0;

      for( unsigned int j=0; j<nrows[k]; j++ ){
	float m = matrix[k][j];
	if( m ){
	  pixel[k] += (m == 1.0) ? ((float*)rawtile.data)[n+j] : ((float*)rawtile.data)[n+j] * m;
	}
      }
    }

    // Only write our values at the end as we reuse channel values several times during the twist loops
    for( int k=0; k<rawtile.channels; k++ ) ((float*)rawtile.data)[n++] = pixel[k];

  }
  delete[] nrows;
  delete[] pixel;
}
void Transform::twist( RawTile& rawtile, const vector< vector<float> >& matrix ){

  unsigned long np = rawtile.width * rawtile.height;

   
  float* pixel = new float[rawtile.channels];

   
  unsigned int ncols = (matrix.size()>(unsigned int)rawtile.channels) ? rawtile.channels : matrix.size();
  unsigned int* nrows = new unsigned int[ncols];

   
  for( unsigned int i=0; i<ncols; i++ ){
    nrows[i] = (matrix[i].size()>(unsigned int)rawtile.channels) ? rawtile.channels : matrix[i].size();
  }


  for( unsigned long i=0; i<np; i++ ){

    unsigned long n = i*rawtile.channels;

     
    for( unsigned int k=0; k<ncols; k++ ){

       
      pixel[k] = 0.0;

      for( unsigned int j=0; j<nrows[k]; j++ ){
	float m = matrix[k][j];
	if( m ){
	  pixel[k] += (m == 1.0) ? ((float*)rawtile.data)[n+j] : ((float*)rawtile.data)[n+j] * m;
	}
      }
    }

     
    for( int k=0; k<rawtile.channels; k++ ) ((float*)rawtile.data)[n++] = pixel[k];

  }
  delete[] nrows;
  delete[] pixel;
}