public static void decode(InputStream in, OutputStream out, boolean throwExceptions)
      throws IOException {
    // Base64 decoding converts four bytes of input to three bytes of output
    int[] inBuffer = new int[4];

    // read bytes un-mapping them from their ASCII encoding in the process
    // we must read at least two bytes to be able to output anything
    boolean done = false;
    while (!done && (inBuffer[0] = readBase64(in, throwExceptions)) != END_OF_INPUT
        && (inBuffer[1] = readBase64(in, throwExceptions)) != END_OF_INPUT) {
      // Fill the buffer
      inBuffer[2] = readBase64(in, throwExceptions);
      inBuffer[3] = readBase64(in, throwExceptions);

      // Calculate the output
      // The first two bytes of our in buffer will always be valid
      // but we must check to make sure the other two bytes
      // are not END_OF_INPUT before using them.
      // The basic idea is that the four bytes will get reconstituted
      // into three bytes along these lines:
      // [xxAAAAAA] [xxBBBBBB] [xxCCCCCC] [xxDDDDDD]
      //      [AAAAAABB] [BBBBCCCC] [CCDDDDDD]
      // bytes are considered to be zero when absent.

      // six A and two B
      out.write(inBuffer[0] << 2 | inBuffer[1] >> 4);
      if (inBuffer[2] != END_OF_INPUT) {
        // four B and four C
        out.write(inBuffer[1] << 4 | inBuffer[2] >> 2);
        if (inBuffer[3] != END_OF_INPUT) {
          // two C and six D
          out.write(inBuffer[2] << 6 | inBuffer[3]);
        } else {
          done = true;
        }
      } else {
        done = true;
      }
    }
    out.flush();
  }
public static void decode ( InputStream in , OutputStream out , boolean throwExceptions ) throws IOException { int [ ] inBuffer = new int [ 4 ] ; boolean done = false ; while ( ! done && ( inBuffer [ 0 ] = readBase64 ( in , throwExceptions ) ) != END_OF_INPUT && ( inBuffer [ 1 ] = readBase64 ( in , throwExceptions ) ) != END_OF_INPUT ) { inBuffer [ 2 ] = readBase64 ( in , throwExceptions ) ; inBuffer [ 3 ] = readBase64 ( in , throwExceptions ) ; out . write ( inBuffer [ 0 ] << 2 | inBuffer [ 1 ] > > 4 ) ; if ( inBuffer [ 2 ] != END_OF_INPUT ) { out . write ( inBuffer [ 1 ] << 4 | inBuffer [ 2 ] > > 2 ) ; if ( inBuffer [ 3 ] != END_OF_INPUT ) { out . write ( inBuffer [ 2 ] << 6 | inBuffer [ 3 ] ) ; } else { done = true ; } } else { done = true ; } } out . flush ( ) ; }
Decode Base64 encoded data from the InputStream to the OutputStream. Characters in the Base64
alphabet, white space and equals sign are expected to be in url encoded data.  The presence of
other characters could be a sign that the data is corrupted.

@param in Stream from which to read data that needs to be decoded.
@param out Stream to which to write decoded data.
@param throwExceptions Whether to throw exceptions when unexpected data is encountered.
@throws IOException if an IO error occurs.
@throws Base64DecodingException if unexpected data is encountered when throwExceptions is
specified.
@since ostermillerutils 1.00.00