public class Frame
{
  private int height;
  private int width;
  private int channels;
  private byte[][][] data;

  Frame( int height, int width, int channels )
  {
    this.height = height;
    this.width = width;
    this.channels = channels;
    data = new byte[height][width][channels];
  }

  Frame( Frame frame )
  {
    height = frame.height;
    width = frame.width;
    channels = frame.channels;
    data = (byte[][][])frame.data.clone( );
  }

  public void setData( int maxval, byte[] rawData, int startIndex )
  {
    int i, h, w, c;
    for( i = startIndex, h = 0; h < height; h++ )
      for( w = 0; w < width; w++ )
        for( c = 0; c < channels; c++, i++ )
          if( rawData[i] > maxval )
            data[h][w][c] = (byte)255;
          else
            data[h][w][c] = (byte)((rawData[i] & 0xFF) * 255 / maxval);
  }

  public int getHeight( )
  {
    return height;
  }

  public int getWidth( )
  {
    return width;
  }

  public int getChannels( )
  {
    return channels;
  }

  public byte[][][] getData( )
  {
    return data;
  }

  public void resize( int height, int width, int channels )
  {
    byte[][][] data;
    int y, x, c;
    int emptyY, emptyX, skipY, skipX, rangeY, rangeX, val;

    data = new byte[height][width][channels];
    for( y = 0; y < height; y++ )
      for( x = 0; x < width; x++ )
        for( c = 0; c < channels; c++ )
          data[y][x][c] = 0;

    if( height > this.height )
    {
      emptyY = (height - this.height) / 2; 
      skipY = 0;
      rangeY = this.height;
    }
    else
    {
      emptyY = 0;
      skipY = (this.height - height) / 2;
      rangeY = height;
    }
    if( width > this.width )
    {
      emptyX = (width - this.width) / 2; 
      skipX = 0;
      rangeX = this.width;
    }
    else
    {
      emptyX = 0;
      skipX = (this.width - width) / 2;
      rangeX = width;
    }

    for( y = 0; y < rangeY; y++ )
    {
      for( x = 0; x < rangeX; x++ )
      {
        val = 0;
        for( c = 0; c < this.channels; c++ )
          val += this.data[skipY + y][skipX + x][c] & 0xFF;
        val /= this.channels;
        for( c = 0; c < channels; c++ )
          data[emptyY + y][emptyX + x][c] = (byte)val;
      }
    }

    this.height = height;
    this.width = width;
    this.channels = channels;
    this.data = data;
  }

  public String toString( )
  {
    String str = "";
    int h, w, c, val;
    for( h = 0; h < height; h++ )
    {
      for( w = 0; w < width; w++ )
      {
        val = 0;
        for( val = 0, c = 0; c < channels; c++ )
          val += (data[h][w][c] & 0xFF);
        val /= channels * 32;
        str = str + " -+*%#&@".substring( val, val + 1); 
      }
      str = str + "\n";
    }
    return str;
  }
}
