public ByteBuffer unpredict(ByteBuffer imageData) throws IOException {
  List<byte[]> rows=new ArrayList<byte[]>();
  byte[] curLine=null;
  byte[] prevLine=null;
  int rowSize=getColumns() * getColors() * getBitsPerComponent();
  rowSize=(int)Math.ceil(rowSize / 8.0);
  while (imageData.remaining() >= rowSize + 1) {
    int algorithm=(int)(imageData.get() & 0xff);
    curLine=new byte[rowSize];
    imageData.get(curLine);
switch (algorithm) {
case 0:
      break;
case 1:
    doSubLine(curLine);
  break;
case 2:
doUpLine(curLine,prevLine);
break;
case 3:
doAverageLine(curLine,prevLine);
break;
case 4:
doPaethLine(curLine,prevLine);
break;
}
rows.add(curLine);
prevLine=curLine;
}
ByteBuffer outBuf=ByteBuffer.allocate(rows.size() * rowSize);
for (Iterator i=rows.iterator(); i.hasNext(); ) {
outBuf.put((byte[])i.next());
}
outBuf.flip();
return outBuf;
}

public ByteBuffer unpredict ( ByteBuffer imageData ) throws IOException { List < byte [ ] > rows = new ArrayList < byte [ ] > ( ) ; byte [ ] curLine = null ; byte [ ] prevLine = null ; int rowSize = getColumns ( ) * getColors ( ) * getBitsPerComponent ( ) ; rowSize = ( int ) Math . ceil ( rowSize / 8.0 ) ; while ( imageData . remaining ( ) >= rowSize + 1 ) { int algorithm = ( int ) ( imageData . get ( ) & 0xff ) ; curLine = new byte [ rowSize ] ; imageData . get ( curLine ) ; switch ( algorithm ) { case 0 : break ; case 1 : doSubLine ( curLine ) ; break ; case 2 : doUpLine ( curLine , prevLine ) ; break ; case 3 : doAverageLine ( curLine , prevLine ) ; break ; case 4 : doPaethLine ( curLine , prevLine ) ; break ; } rows . add ( curLine ) ; prevLine = curLine ; } ByteBuffer outBuf = ByteBuffer . allocate ( rows . size ( ) * rowSize ) ; for ( Iterator i = rows . iterator ( ) ; i . hasNext ( ) ; ) { outBuf . put ( ( byte [ ] ) i . next ( ) ) ; } outBuf . flip ( ) ; return outBuf ; }
undo data based on the png algorithm
