pure subroutine decode_bits(code, bits)
!< Decode a base64 string into a sequence of bits stream.
!<
!< The base64 string must be parsed with a strike of 4 characters and converted into a 3 bytes stream. Considering the base64 code
!< `QUJD` the decoding process must do
!<```
!< +-b64 char--+-b64 char--+-b64 char--+-b64 char--+
!< | Q | U | J | D |
!< +-b64 index-+-b64 index-+-b64 index-+-b64 index-+
!< ! 16 | 20 | 9 | 3 |
!< +-6 bits----+-6 bits----+-6 bits----+-6 bits----+
!< |0 1 0 0 0 0|0 1 0 1 0 0|0 0 1 0 0 1|0 0 0 0 1 1|
!< +-----------+---+-------+-------+---+-----------+
!< |0 1 0 0 0 0 0 1|0 1 0 0 0 0 1 0|0 1 0 0 0 0 1 1|
!< +-----8 bits----+-----8 bits----+-----8 bits----+
!<```
!< @note The bits pattern is returned as a 1-byte element array, the dimension of witch must be computed outside this procedure.
!<
!< @warning This procedure is the backend of decoding, thus it must be never called outside the module.
character(*), intent(in) :: code !< Characters code.
integer(I1P), intent(out) :: bits(1:) !< Bits decoded.
integer(I1P) :: sixb(1:4) !< 6 bits slices (stored into 8 bits integer) of 24 bits input.
integer(I8P) :: c !< Counter.
integer(I8P) :: e !< Counter.
integer(I8P) :: Nb !< Length of bits array.
Nb=size(bits,dim=1,kind=I8P)
e = 1_I8P
do c=1_I8P,len(code),4_I8P ! loop over code characters: 3 bytes (24 bits) scanning
sixb = 0_I1P
sixb(1) = index(base64,code(c :c )) - 1
sixb(2) = index(base64,code(c+1:c+1)) - 1
sixb(3) = index(base64,code(c+2:c+2)) - 1
sixb(4) = index(base64,code(c+3:c+3)) - 1
call mvbits(sixb(1),0,6,bits(e ),2) ; call mvbits(sixb(2),4,2,bits(e ),0)
if (e+1<=Nb) then
call mvbits(sixb(2),0,4,bits(e+1),4) ; call mvbits(sixb(3),2,4,bits(e+1),0)
endif
if (e+2<=Nb) then
call mvbits(sixb(3),0,2,bits(e+2),6) ; call mvbits(sixb(4),0,6,bits(e+2),0)
endif
e = e + 3_I8P
enddo
endsubroutine decode_bits