public static final void decode(InputStream is,OutputStream os) throws Base64DecodingException, IOException {
  byte b1=0, b2=0, b3=0, b4=0;
  int index=0;
  byte[] data=new byte[4];
  int read;
  while ((read=is.read()) > 0) {
    byte readed=(byte)read;
    if (isWhiteSpace(readed)) {
      continue;
    }
    if (isPad(readed)) {
      data[index++]=readed;
      if (index == 3) {
        data[index++]=(byte)is.read();
      }
      break;
    }
    if ((data[index++]=readed) == -1) {
      throw new Base64DecodingException("decoding.general");
    }
    if (index != 4) {
      continue;
    }
    index=0;
    b1=base64Alphabet[data[0]];
    b2=base64Alphabet[data[1]];
    b3=base64Alphabet[data[2]];
    b4=base64Alphabet[data[3]];
    os.write((byte)(b1 << 2 | b2 >> 4));
    os.write((byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
    os.write((byte)(b3 << 6 | b4));
  }
  byte d1=data[0], d2=data[1], d3=data[2], d4=data[3];
  b1=base64Alphabet[d1];
  b2=base64Alphabet[d2];
  b3=base64Alphabet[d3];
  b4=base64Alphabet[d4];
  if ((b3 == -1) || (b4 == -1)) {
    if (isPad(d3) && isPad(d4)) {
      if ((b2 & 0xf) != 0) {
        throw new Base64DecodingException("decoding.general");
      }
      os.write((byte)(b1 << 2 | b2 >> 4));
    }
 else     if (!isPad(d3) && isPad(d4)) {
      b3=base64Alphabet[d3];
      if ((b3 & 0x3) != 0) {
        throw new Base64DecodingException("decoding.general");
      }
      os.write((byte)(b1 << 2 | b2 >> 4));
      os.write((byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
    }
 else {
      throw new Base64DecodingException("decoding.general");
    }
  }
 else {
    os.write((byte)(b1 << 2 | b2 >> 4));
    os.write((byte)(((b2 & 0xf) << 4) | ((b3 >> 2) & 0xf)));
    os.write((byte)(b3 << 6 | b4));
  }
}

public static final void decode ( InputStream is , OutputStream os ) throws Base64DecodingException , IOException { byte b1 = 0 , b2 = 0 , b3 = 0 , b4 = 0 ; int index = 0 ; byte [ ] data = new byte [ 4 ] ; int read ; while ( ( read = is . read ( ) ) > 0 ) { byte readed = ( byte ) read ; if ( isWhiteSpace ( readed ) ) { continue ; } if ( isPad ( readed ) ) { data [ index ++ ] = readed ; if ( index == 3 ) { data [ index ++ ] = ( byte ) is . read ( ) ; } break ; } if ( ( data [ index ++ ] = readed ) == - 1 ) { throw new Base64DecodingException ( "decoding.general" ) ; } if ( index != 4 ) { continue ; } index = 0 ; b1 = base64Alphabet [ data [ 0 ] ] ; b2 = base64Alphabet [ data [ 1 ] ] ; b3 = base64Alphabet [ data [ 2 ] ] ; b4 = base64Alphabet [ data [ 3 ] ] ; os . write ( ( byte ) ( b1 << 2 | b2 > > 4 ) ) ; os . write ( ( byte ) ( ( ( b2 & 0xf ) << 4 ) | ( ( b3 > > 2 ) & 0xf ) ) ) ; os . write ( ( byte ) ( b3 << 6 | b4 ) ) ; } byte d1 = data [ 0 ] , d2 = data [ 1 ] , d3 = data [ 2 ] , d4 = data [ 3 ] ; b1 = base64Alphabet [ d1 ] ; b2 = base64Alphabet [ d2 ] ; b3 = base64Alphabet [ d3 ] ; b4 = base64Alphabet [ d4 ] ; if ( ( b3 == - 1 ) || ( b4 == - 1 ) ) { if ( isPad ( d3 ) && isPad ( d4 ) ) { if ( ( b2 & 0xf ) != 0 ) { throw new Base64DecodingException ( "decoding.general" ) ; } os . write ( ( byte ) ( b1 << 2 | b2 > > 4 ) ) ; } else if ( ! isPad ( d3 ) && isPad ( d4 ) ) { b3 = base64Alphabet [ d3 ] ; if ( ( b3 & 0x3 ) != 0 ) { throw new Base64DecodingException ( "decoding.general" ) ; } os . write ( ( byte ) ( b1 << 2 | b2 > > 4 ) ) ; os . write ( ( byte ) ( ( ( b2 & 0xf ) << 4 ) | ( ( b3 > > 2 ) & 0xf ) ) ) ; } else { throw new Base64DecodingException ( "decoding.general" ) ; } } else { os . write ( ( byte ) ( b1 << 2 | b2 > > 4 ) ) ; os . write ( ( byte ) ( ( ( b2 & 0xf ) << 4 ) | ( ( b3 > > 2 ) & 0xf ) ) ) ; os . write ( ( byte ) ( b3 << 6 | b4 ) ) ; } }
decodes base64 data into outputstream
